﻿package Server.AHMJ.HSMJ;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;

import Server.Agent.GameDB;
import Server.Model.Base.IRoom;
import Server.Model.Base.IServerUserItem;
import Server.Model.Base.SHMUser;
import Server.Model.Hall.QpGameMgr;
import Server.Model.Hall.dthall;
import club.ClubRedis;
import redis.protocal.DbInfoMgr;

public class MajTable extends IRoom {
	/**
	 * 胡的方式
	 */
	public static int hu_Index = -1;
	/**
	 * 胡的类型
	 */
	public static int hu_Type = -1;
	/**
	 * 可胡的索引
	 */
	public ArrayList<Integer> hu_Indexes = new ArrayList<Integer>();

	M_tempAction m_tempAction[] = new M_tempAction[4];

	{
		for (int i = 0; i < 4; i++) {
			m_tempAction[i] = new M_tempAction();
		}
	}

	@Override
	public int GetID() {
		return m_dwTableID;
	};

	@Override
	public String GetType() {
		return "HSMJ";
	};

	@Override
	public int GetCreator() {
		return m_Creator;
	}

	@Override
	public void OnClientClose(int uid) {
		OnUserStandUp(uid, false);
	};

	@Override
	public int CanSit(int _Uid) {

		SHMUser user = dthall.getInstance().getUserInfo(_Uid);
		if (user != null) {
			int check = m_maxCostGem;
			if (this.m_hqInZuanNum != 0 && this.m_hqInZuanNum > check)
				check = this.m_hqInZuanNum;
			if (user.getGem(0) < check) {
				if (m_payWay != "FZPAY") {
					return 11;
				}
			}
		}

		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID == _Uid) {
				return i;
			}
		}
		this.m_hqIpLimit = false;
		if (this.m_hqGpsLimit) {
			// TODO
		}

		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID == 0) {
				return i;
			}
		}
		return 12;
	};

	@Override
	public int FindSeat(int _Uid) {
		for (int bySeatID = 0; bySeatID < 4; bySeatID++) {
			if (m_pIUserItem[bySeatID].dwUserID == _Uid) {
				return bySeatID;
			}
		}
		return Constants.INVALID_CHAIR;
	}

	MajLogic m_MajLogic = new MajLogic();
	MajPaiQiang m_MajPaiQiang = new MajPaiQiang();

	int m_caiShen = Constants.INVALID_CARD;
	int fan_caiShen = Constants.INVALID_CARD;

	int m_vecGuiPai[] = new int[2];
	int m_vecMaPai[] = new int[9];
	// 获取杠牌的信息
	Map<Integer, List<BLOCK_GANGINFO>> userGangInfos = new HashMap<Integer, List<BLOCK_GANGINFO>>();

	List<BLOCK_GANGINFO> gangInfosOf(Integer user) {
		List<BLOCK_GANGINFO> gangInfos = userGangInfos.get(user);
		if (gangInfos == null) {
			gangInfos = new ArrayList<BLOCK_GANGINFO>();
			userGangInfos.put(user, gangInfos);
		}
		return gangInfos;
	}

	// 获取碰的信息
	Map<Integer, List<BLOCK_PONGINFO>> userPongInfos = new HashMap<Integer, List<BLOCK_PONGINFO>>();

	List<BLOCK_PONGINFO> pongInfosOf(Integer user) {
		List<BLOCK_PONGINFO> pongInfos = userPongInfos.get(user);
		if (pongInfos == null) {
			pongInfos = new ArrayList<BLOCK_PONGINFO>();
			userPongInfos.put(user, pongInfos);
		}
		return pongInfos;
	}

	//
	boolean m_bTianHu; // 天胡可能
	boolean m_bDiHu[] = new boolean[4]; // 地胡可能
	boolean m_bRenHu[] = new boolean[4]; // 人胡可能
	boolean m_bQiangGangHu[] = new boolean[4]; // 人胡可能
	boolean m_bTing[] = new boolean[4];
	boolean m_bDiTing[] = new boolean[4]; // 地听可能
	int m_byTing[] = new int[4];
	int m_byChuPaiCount[] = new int[4]; // 出了多少张牌可能
	int m_byMingGang[] = new int[4];
	int m_byAnGang[] = new int[4];
	int m_byBuGang[] = new int[4];
	int m_byDianGang[] = new int[4];
	long m_dwLastDoCmdTime;
	int m_byRight[][] = new int[4][6];
	boolean m_bIsHu[] = new boolean[4]; // 是否胡了
	int m_qiuPaiNum[][] = new int[5][5];// 座位号 对 座位号的吃碰次数
	boolean m_bIsAllowHu[] = new boolean[4];// 座位号 对 座位号的吃碰次数
	boolean m_bIsGang[] = new boolean[4];// 胡牌前是否杠牌了为了判断杠底花

	int outMjs[][] = new int[4][4];

	int countKehu = 0;
	/**
	 * 统计明杠和补杠的总分
	 */
	int mingGangFen[] = new int[4];

	/**
	 * 用于处理多人抢杠胡牌
	 */
	boolean m_hasYiPaoSanXiang = false;

	boolean m_isBusy = false;

	/**
	 * 处理多人抢杠胡
	 */
	int m_roundHuCount = 0;
	int m_roundHuGetCount = 0;
	int m_roundHuSeated[] = new int[4];
	/**
	 * 是否是多人抢杠胡
	 */
	int LastOutNum = 0;
	/**
	 * 上一家的分数
	 */
	int LastOutOld[] = new int[4];
	/**
	 * 代表输赢分数
	 */
	int roundScore[] = new int[4];

	int nextPai = 0;// 控制得到下张牌
	int seatId = -1;

	int l_seat = -1;
	int l_handMj[] = new int[13];

	boolean m_bCengBao = false;
	// 多局一共的结算
	tagUserReport m_kReport[] = new tagUserReport[4];

	{
		for (int i = 0; i < 4; i++) {
			m_kReport[i] = new tagUserReport();
		}
	}

	public int m_hqInZuanNum = 0;
	Long m_lStartTime;
	long needDealTime;
	public int m_dwTableID;
	long m_dismissTimer;
	int m_byAgreeDismiss[] = new int[4];
	boolean m_bTableStarted;
	boolean m_bGameStarted;
	int m_byRound;
	int m_byMaxRound;
	int m_wChuPaiDelay;
	int m_wFaPaiDelay;// 发牌延迟
	long m_wRobotSeconds[] = new long[4]; // 等待时长
	public boolean m_hqIpLimit = false;
	long m_wJieSuanRound;
	public int m_byCostGem;
	public int m_maxCostGem;
	public int m_diFen = 0;
	public int m_fdFen = 0;
	public String m_payWay;
	public String m_strParam;
	public String m_strRoomDesc;
	public boolean m_hqGpsLimit = false;
	public String[] m_vecParam;
	//四个玩法
	public Boolean m_xiaoBao = false;
	public Boolean m_fengYiSe = false;
	public Boolean m_tiandiHu = false;
	public Boolean m_siBao = false;
	public String m_vecInputWenZi;
	public int m_lastZhuang = 0;
	public int m_byZhuang;// 当前庄位置
	public int m_byLianZhuang;// 当前庄位置
	/**
	 * 赢的那个人的id
	 */
	public int m_winSeatID = -1;
	public int m_vecWinScore[] = new int[5];
	public int m_vecLoseScore[] = new int[5];
	public int m_vecGangScore[] = new int[5];
	public int m_vecRoundScore[] = new int[5];
	public int m_vecResultScore[] = new int[5];
	public int m_vecZiMo[] = new int[5];
	public String[] m_TouXiang = new String[5];

	public String[] m_vecHuType = new String[5];
	public int m_nPiao;
	public int m_nMaxGuiPai;
	public int m_nMaxMaPai;
	public int m_dhfb = 1;
	public int m_maPaiCount = 4;
	public int m_hutype = 1;
	public int m_jiama = 1;
	public int lastZhuang = 0;

	/**
	 * 庄分 为0 代表无庄 1代表庄分为1 2代表庄分为2;
	 */
	public int m_zhuang = 0;
	/**
	 * 庄分
	 */
	public int m_zhuangFen = 0;
	public int m_Creator;// 房主
	IServerUserItem m_pIUserItem[] = new IServerUserItem[5]; // 用户指针
	public List<MJ_Action> m_history = new ArrayList<MJ_Action>();

	{
		for (int i = 0; i < m_pIUserItem.length; i++) {
			m_pIUserItem[i] = new IServerUserItem();
		}
	}

	long m_LookOnUserID[] = new long[50];// ¹ÛÖÚ

	public static boolean isGameEnd = false;

	public int m_createTime = 0;

	MajTable() {
		m_createTime = (int) (System.currentTimeMillis() / 1000);
		m_byZhuang = 0;
		m_byLianZhuang = 1;
		m_Creator = 0;
		m_wJieSuanRound = 0L;
		m_bTableStarted = false;
		m_strParam = "";
		m_strRoomDesc = "";
		m_byCostGem = 0;
		m_payWay = "FZPAY";
		m_byRound = 0;
		m_byMaxRound = 0;
		m_maxCostGem = 0;
		m_nPiao = 0;
		m_diFen = 1;
		m_fdFen = 1000;
		m_nMaxGuiPai = 0;
		m_nMaxMaPai = 0;
		countKehu = 0;
	}

	void Init(int cbReason) {
		Constants.memset(LastOutOld, 0, 4);
		Constants.memset(roundScore, 0, 4);
		Constants.memset(mingGangFen, 0, 4);
		m_bGameStarted = false;
		m_dwLastDoCmdTime = 0L;
		m_bTianHu = true;
		m_vecInputWenZi="";	
		m_wChuPaiDelay = 0;
		m_wFaPaiDelay = 0;
		m_wDealErrorDelay = 1;

		m_bCengBao = false;
		m_isBusy = false;
		m_roundHuCount = 0;
		m_roundHuGetCount = 0;
		// 胡的信息
		hu_Type = -1;
		hu_Index = -1;
		hu_Indexes.clear();
		////
		/**
		 * 处理是否是多人抢杠胡
		 */
		LastOutNum = 0;
		for (int i = 0; i < 4; i++) {
			m_roundHuSeated[i] = -1;
		}

		CleanTempAction();
		m_history.clear();
		m_caiShen = 255;
		for (int i = 0; i < 4; i++) {
			m_qiuPaiNum = new int[5][5];// 新一局的吃碰次数
			if (i == m_byZhuang) {
				m_bDiHu[i] = false;// 庄没有地胡这一说
				m_bRenHu[i] = false;// 庄没有人胡这一说
			} else {
				m_bDiHu[i] = true;
				m_bRenHu[i] = true;
			}

			m_bDiTing[i] = false;
			m_bQiangGangHu[i] = false;
			// m_bDiHu[i] = true;
			// m_bRenHu[i] = true;
			m_bTing[i] = false;
			m_bIsHu[i] = false;
			m_bIsAllowHu[i] = true;
			m_byTing[i] = 0;
			m_byChuPaiCount[i] = 0;

			m_byMingGang[i] = 0;
			m_byAnGang[i] = 0;
			m_byBuGang[i] = 0;

			m_byDianGang[i] = 0;
			m_wRobotSeconds[i] = 0L;

			m_pIUserItem[i].cbUserStatus = Constants.US_NULL;
			m_vecGangScore[i] = 0;
			m_vecRoundScore[i] = 0;
			m_vecZiMo[i] = 0;
			m_vecHuType[i] = "";
		}
		for (int i = 0; i < 4; i++) {
			m_byRight[i][0] = 0;
			m_byRight[i][1] = 0;
			m_byRight[i][2] = 0;
			m_byRight[i][3] = 0;
			m_byRight[i][4] = 0;
			m_byRight[i][5] = 0;
		}

		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				outMjs[i][j] = 0;
			}
		}

		if (Constants.INIT_TOTAL == cbReason) {
			m_bTableStarted = false;
			m_dismissTimer = 0L;
			m_wJieSuanRound = 0L;
			m_byAgreeDismiss[0] = 0;
			m_byAgreeDismiss[1] = 0;
			m_byAgreeDismiss[2] = 0;
			m_byAgreeDismiss[3] = 0;

			// Constants.memset(&m_kReport, 0, Constants.sizeof(m_kReport));
			// //add

			// Constants.memset(m_pIUserItem, 0,
			// Constants.sizeof(m_pIUserItem)); //add
			Constants.memset(m_LookOnUserID, 0, Constants.sizeof(m_LookOnUserID)); //
			m_MajLogic.Init(Constants.INIT_TOTAL);
			m_byRound = 0;
			m_byZhuang = 0;
			for (int i = 0; i < 4; i++) {
				m_vecWinScore[i] = 0;
				m_vecLoseScore[i] = 0;
				m_vecResultScore[i] = 0;
			}
		}
		if (Constants.INIT_FIRST_ROUND == cbReason) {
			m_MajLogic.Init(Constants.INIT_FIRST_ROUND);
		}
		if (Constants.INIT_NEWROUND == cbReason) {
			m_MajLogic.Init(Constants.INIT_NEWROUND);
		}

	}

	/**
	 * 处理多人胡的情况
	 */
	void clearRoundHu() {
		// this.m_hasYiPaoSanXiang = false;
		this.m_roundHuCount = 0;
		this.m_roundHuGetCount = 0;
		for (int i = 0; i < 4; i++) {
			m_roundHuSeated[i] = -1;
		}
	}

	void clearUserHuRound(int seatId) {
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] == seatId) {
				m_roundHuSeated[i] = -1;
			}
		}
	}

	boolean IsYiPaoSanXiang() {
		int count = 0;
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] >= 0)
				count++;
		}
		return count > 1;
	}

	boolean IsInRoundHu(int seatId) {
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] == seatId)
				return true;
		}
		return false;
	}

	boolean IsFirstRoundHu(int seatId) {
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] >= 0 && m_roundHuSeated[i] == seatId)
				return true;
			else if (m_roundHuSeated[i] >= 0 && m_roundHuSeated[i] != seatId)
				return false;
		}
		return false;
	}

	int GetRoundHuIndex(int seatId) {
		int index = 0;
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] >= 0) {
				if (m_roundHuSeated[i] == seatId)
					return index;
				else
					index++;
			}
		}
		return -1;
	}

	void KickRobots() {
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].isAndroidUser == 1) {

			}
		}
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].isAndroidUser == 1) {

			}
		}
	}

	boolean HasRobot() {
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].isAndroidUser == 1) {
				return true;
			}
		}
		return false;
	}

	void SendAvatar(int _Uid) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}
		String iter = dthall.getInstance().Handle_OnGetUserAvatar(_Uid);

		SUBCMD_S_Avatar cmd = new SUBCMD_S_Avatar();
		cmd.m_lUid = _Uid;
		if (!StringUtils.isEmpty(iter)) {
			m_TouXiang[wChairID]=iter;
			cmd.szAvatarURL = iter;
		} else {
			cmd.szAvatarURL = "http://lamj.qilehuyu.cn/liuan-80.png";
		}

		SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());
	}

	public void SendLocationData(SHMUser user) {
		JSONObject data = new JSONObject();
		data.put("loc", user.getGpsLocInfo());
		data.put("uid", user.getUid());
		data.put("command", "GPS_LOC");
		SendTableData(Constants.INVALID_CARD, data.toString());

		for (short i = 0; i < m_pIUserItem.length; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				if (m_pIUserItem[i].isAndroidUser == 0) {
					int uid = m_pIUserItem[i].dwUserID;
					SHMUser other = dthall.getInstance().getUserInfo(uid);
					if(other != null){
						data.put("uid", other.getUid());
						data.put("loc", other.getGpsLocInfo());
						dthall.getInstance().onSend(user.getUid(), data.toString());
					}
				}
			}
		}
	}

	public void SendGpsData(SHMUser user) {
		JSONObject data = new JSONObject();
		List<Double> gpsData = user.getLocateInfo();
		data.put("lng", gpsData.get(0));
		data.put("lat", gpsData.get(1));
		data.put("command", "GPS_DATA");
		data.put("uid", user.getUid());
		SendTableData(Constants.INVALID_CHAIR, data.toString());

		for (short i = 0; i < m_pIUserItem.length; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				if (m_pIUserItem[i].isAndroidUser == 0) {
					int uid = m_pIUserItem[i].dwUserID;
					SHMUser other = dthall.getInstance().getUserInfo(uid);
					if (other != null) {
						gpsData = other.getLocateInfo();
						data.put("uid", other.getUid());
						data.put("lng", gpsData.get(0));
						data.put("lat", gpsData.get(1));
						dthall.getInstance().onSend(user.getUid(), data.toString());
					}
				}
			}
		}
	}

	public void OnUserSit(int _Uid) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID < 5) {
			m_pIUserItem[bySeatID].cbOnline = Constants.US_NULL;
		}
		SHMUser user = dthall.getInstance().getUserInfo(_Uid);
		if (user != null) {
			SendGpsData(user);
			SendLocationData(user);
		}
		if (user != null) {
			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID == _Uid) {
					m_wRobotSeconds[i] = 0L;
					m_pIUserItem[i].dwUserID = _Uid;

					m_pIUserItem[i].wChairID = i;
					m_pIUserItem[i].dwFaceID = user.getAvatar();
					m_pIUserItem[i].cbGender = user.getSex();
					m_pIUserItem[i].cbOnline = 0;
					m_pIUserItem[i].szNickName = user.getNickName(null);
					m_pIUserItem[i].szIP = user.getIP(null);

					SUBCMD_S_Sit cmd = new SUBCMD_S_Sit();

					cmd.m_lUid = _Uid;
					cmd.m_wUserChairID = m_pIUserItem[i].wChairID;
					cmd.m_dwTableID = m_dwTableID;
					cmd.m_lUserScore = m_pIUserItem[i].lUserScore;
					cmd.m_cbGender = m_pIUserItem[i].cbGender;
					cmd.m_iAvatar = m_pIUserItem[i].dwFaceID;
					cmd.szNickName = user.getNickName(null);
					cmd.szIP = m_pIUserItem[i].szIP;

					SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());

					if (m_bGameStarted) {
						SendGameScene(_Uid, Constants.GS_PLAYING);
					} else {
						SendGameScene(_Uid, Constants.GS_FREE);
					}

					SendAvatar(m_pIUserItem[i].dwUserID);
					return;
					// return m_pIUserItem[i].wChairID;
				}
			}
			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID == 0) {
					m_wRobotSeconds[i] = 0L;
					m_pIUserItem[i].dwUserID = _Uid;
					m_pIUserItem[i].lUserScore = 0;
					m_pIUserItem[i].wChairID = i;
					m_pIUserItem[i].dwFaceID = user.getAvatar();
					m_pIUserItem[i].cbGender = user.getSex();
					m_pIUserItem[i].cbOnline = 0;
					m_pIUserItem[i].szNickName = user.getNickName(null);
					m_pIUserItem[i].szIP = user.getIP(null);

					SUBCMD_S_Sit cmd = new SUBCMD_S_Sit();

					cmd.m_lUid = _Uid;
					cmd.m_wUserChairID = m_pIUserItem[i].wChairID;
					cmd.m_dwTableID = m_dwTableID;
					cmd.m_lUserScore = m_pIUserItem[i].lUserScore;
					cmd.m_cbGender = m_pIUserItem[i].cbGender;
					cmd.m_iAvatar = m_pIUserItem[i].dwFaceID;
					cmd.szNickName = user.getNickName(null);
					cmd.szIP = m_pIUserItem[i].szIP;

					SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());

					if (m_bGameStarted) {
						SendGameScene(_Uid, Constants.GS_PLAYING);
					} else {
						SendGameScene(_Uid, Constants.GS_FREE);
					}

					return;
					// / return m_pIUserItem[i].wChairID;
				}
			}

		}
		return;
		// return (int)Constants.INVALID_CHAIR;
	}

	int FindSeat(long _Uid) {
		for (int bySeatID = 0; bySeatID < 4; bySeatID++) {
			if (m_pIUserItem[bySeatID].dwUserID == _Uid) {
				return bySeatID;
			}
		}
		return Constants.INVALID_CHAIR;
	}

	int GetPlayerCount() {
		int cntPlayer = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				cntPlayer++;
			}
		}
		return cntPlayer;
	}

	int GetRobotCount() {
		int cntPlayer = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].isAndroidUser == 1) {
				cntPlayer++;
			}
		}
		return cntPlayer;
	}

	public void OnUserStandUp(int _Uid, boolean leaveroom) {
		int wChairID = FindSeat(_Uid);
		if (m_bTableStarted == false && wChairID != 0 && leaveroom == true) {
			SUBCMD_S_StandUp cmd = new SUBCMD_S_StandUp();
			cmd.m_lUid = _Uid;
			cmd.m_wUserChairID = wChairID;
			cmd.m_dwTableID = m_dwTableID;
			SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());
		}

		if (m_bTableStarted == false && leaveroom == true) {
			if (wChairID > 0 && wChairID < 5) {
				m_pIUserItem[wChairID].Init();
				QpGameMgr.getInstance().OnRemoveUserRoom(_Uid);
			} else {
			}
		} else {
			if (wChairID < 5) {
				m_pIUserItem[wChairID].cbOnline = Constants.US_OFFLINE;
			}
		}
	}

	// 踢人
		public void Handle_Kick(int _uid, String[] arg) {
			Integer _Uid = Integer.parseInt(arg[1]);
			int seat = FindSeat(_Uid);
			SUBCMD_S_Kick cmd = new SUBCMD_S_Kick();
			cmd.m_lUid = _Uid;
			cmd.m_wUserChairID = seat;
			SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());
			m_pIUserItem[seat].Init();
			QpGameMgr.getInstance().OnRemoveUserRoom(_Uid);
		}
	
	public boolean HasParam(String szKey, boolean defaultValue) {
		for (int i = 0; i < m_vecParam.length; i++) {
			String key = m_vecParam[i];
			if (key.equals(szKey)) {
				return true;
			}
		}
		return defaultValue;
	}

	public void SetParam(String szParam) {
		m_strParam = szParam;

		m_vecParam = m_strParam.split(";");
	}

	public void SetDesc(String szDesc) {
		m_strRoomDesc = szDesc;

	}

	boolean SendYuPai() {
		SUBCMD_S_YuPai cmd = new SUBCMD_S_YuPai();
		cmd.byYuPai = m_MajPaiQiang.GetYuPaiCount();
		cmd.byCurrentUser = m_MajLogic.GetCurrentUser();

		SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());
		// SendLookonData(Constants.INVALID_CHAIR, cmd.getJsonData());
		return true;
	}

	boolean TZChuPai(int bySeatID) {
		if (bySeatID >= 0 && bySeatID <= 4) {
			if (m_pIUserItem[bySeatID].dwUserID > 0) {
				MajSide lMajSide = m_MajLogic.GetMajSide(bySeatID);
				SUBCMD_S_TZChuPai cmd = new SUBCMD_S_TZChuPai();
				cmd.bySeatID = bySeatID;
				cmd.byTing = lMajSide.byTing;
				Constants.memcpy(cmd.Maj, lMajSide.Maj, 14);
				Constants.memcpy(cmd.Hua, lMajSide.Hua, 8);
				Constants.memcpy(cmd.hu, lMajSide.hu);
				Constants.memcpy(cmd.outMj, lMajSide.outMj, 20);
				Constants.memcpy(cmd.byRight, m_byRight[bySeatID], 6);

				SendData(m_pIUserItem[bySeatID].dwUserID, cmd.getJsonData());
				m_wDealErrorDelay = 0;
			}

			// SendLookonData(Constants.INVALID_CHAIR, cmd.getJsonData());
			return true;
		}
		return false;
	}

	boolean SendGameScene(int _Uid, int bGameStatus) {

		{
			String tmpRoomDesc = m_strRoomDesc;
			SUBCMD_S_Param cmd = new SUBCMD_S_Param();
			cmd.m_dwTableID = m_dwTableID;
			cmd.szParam = m_strParam;
			cmd.szRoomDesc = tmpRoomDesc;
			SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());

		}

		{
			SUBCMD_S_Table cmd = new SUBCMD_S_Table();
			cmd.vecInputWenZi = m_vecInputWenZi;
			cmd.m_dwTableID = m_dwTableID;// 房间ID
			cmd.m_bTableStarted = m_bTableStarted ? 1 : 0;// 房间ID
			cmd.m_bGameStarted = m_bGameStarted ? 1 : 0;// 是否开始
			cmd.m_byYuPai = m_MajPaiQiang.GetYuPaiCount();
			cmd.m_byRound = m_byRound;
			cmd.m_byMaxRound = m_byMaxRound;
			cmd.m_cntLookon = 1;// 观众

			Constants.memset(cmd.m_seatInfo, 0, Constants.sizeof(cmd.m_seatInfo));

			for (int i = 0; i < 4; i++) {
				cmd.m_seatInfo[i].m_lUid = m_pIUserItem[i].dwUserID;// UID
				cmd.m_seatInfo[i].m_iSeatId = i;// 座位号ID
				cmd.m_seatInfo[i].m_iTotalCoin = m_pIUserItem[i].lUserScore;

				cmd.m_seatInfo[i].m_NickName = m_pIUserItem[i].szNickName;// NICKNAME
				cmd.m_seatInfo[i].m_iBetCoin = 0;//
				cmd.m_seatInfo[i].m_cbGender = m_pIUserItem[i].cbGender;
				cmd.m_seatInfo[i].m_iAvatar = m_pIUserItem[i].dwFaceID;//
				cmd.m_seatInfo[i].m_cbUserStatus = m_pIUserItem[i].cbUserStatus;// 用户状态
				cmd.m_seatInfo[i].m_iVipLevel = m_pIUserItem[i].cbVipLevel;// VIP
																			// LEVEL
				cmd.m_seatInfo[i].m_iTitle = 0;// 称号
				cmd.m_seatInfo[i].m_isLookon = 0;// 是否观众
				cmd.m_seatInfo[i].szIP = m_pIUserItem[i].szIP;
			}

			SendData(_Uid, cmd.getJsonData());
			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					SendAvatar(m_pIUserItem[i].dwUserID);
				}
			}
		}

		if (m_bGameStarted == true) {
			{
				SUBCMD_S_TableBegin cmd = new SUBCMD_S_TableBegin();
				cmd.strParam = m_strParam;
				cmd.byZhuang = m_byZhuang;// 是否开始
				cmd.byYuPai = m_MajPaiQiang.GetYuPaiCount();
				cmd.byRound = m_byRound;
				cmd.byMaxRound = m_byMaxRound;
				cmd.byCurrentUser = m_MajLogic.GetCurrentUser();
				cmd.m_byLianZhuang = m_byLianZhuang;
				cmd.lastZhuang = lastZhuang;
				for (int i = 0; i < 4; i++) {
					cmd.lScore[i] = m_pIUserItem[i].lUserScore;
					cmd.lRoundScore[i] = m_vecRoundScore[i];
				}

				cmd.byLastOutMj = m_MajLogic.GetLastOutMj();
				cmd.fanPai = fan_caiShen;
				cmd.byGuiPai[0] = m_caiShen;
				cmd.byGuiPai[1] = 255;

				SendData(_Uid, cmd.getJsonData());
			}
			{

				for (int i = 0; i < 4; i++) {
					if (m_pIUserItem[i].dwUserID > 0) {
						MajSide lMajSide = m_MajLogic.GetMajSide(i);
						SUBCMD_S_TableSide cmd = new SUBCMD_S_TableSide();
						cmd.bySeatID = i;
						cmd.byTing = lMajSide.byTing;
						Constants.memcpy(cmd.Maj, lMajSide.Maj, 14);
						Constants.memcpy(cmd.Hua, lMajSide.Hua, 8);
						Constants.memcpy(cmd.hu, lMajSide.hu);
						Constants.memcpy(cmd.outMj, lMajSide.outMj, 20);
						Constants.memcpy(cmd.byRight, m_byRight[i], 6);

						SendData(_Uid, cmd.getJsonData());
					}
				}
			}
			{
				SUBCMD_S_TableEnd cmd = new SUBCMD_S_TableEnd();

				SendData(_Uid, cmd.getJsonData());
			}
		}

		return true;
	}

	public Replay Replay = new Replay();

	public boolean SendTableData(int wChairID, String sData) {
		// 群发用户
		if (wChairID == Constants.INVALID_CHAIR) {
			for (short i = 0; i < m_pIUserItem.length; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					if (m_pIUserItem[i].isAndroidUser == 0) {
						dthall.getInstance().onSend(m_pIUserItem[i].dwUserID, sData);
						Replay.AddJsonMsg(i, sData);
					} else {
						Replay.AddJsonMsg(i, sData);
						// mPlayers[i].SendGameMessage(wSubCmdID, pData,
						// wDataSize, data);
					}
				}
			}

			return true;
		} else {
			if (wChairID >= m_pIUserItem.length)
				return true;
			if (m_pIUserItem[wChairID].dwUserID > 0) {
				if (m_pIUserItem[wChairID].isAndroidUser == 0) {
					Replay.AddJsonMsg(wChairID, sData);
					dthall.getInstance().onSend(m_pIUserItem[wChairID].dwUserID, sData);
				} else {
					Replay.AddJsonMsg(wChairID, sData);
					// mPlayers[wChairID].SendGameMessage(wSubCmdID, pData,
					// wDataSize, data);
				}
				return true;
			}
		}

		return false;
	}

	public boolean SendData(int wChairID, String sData) {
		// 群发用户
		if (wChairID == Constants.INVALID_CHAIR) {
			for (short i = 0; i < m_pIUserItem.length; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					if (m_pIUserItem[i].isAndroidUser == 0) {
						Replay.AddJsonMsg(i, sData);
						dthall.getInstance().onSend(m_pIUserItem[i].dwUserID, sData);
					} else {
						Replay.AddJsonMsg(i, sData);
						// mPlayers[i].SendGameMessage(wSubCmdID, pData,
						// wDataSize, data);
					}
				}
			}

			return true;
		} else {
			if (wChairID >= m_pIUserItem.length && wChairID >= 1000) {
				dthall.getInstance().onSend(wChairID, sData);
				int sit = FindSeat(wChairID);
				Replay.AddJsonMsg(sit, sData);
			} else if (m_pIUserItem[wChairID].dwUserID > 0) {
				if (m_pIUserItem[wChairID].isAndroidUser == 0) {
					Replay.AddJsonMsg(wChairID, sData);
					dthall.getInstance().onSend(m_pIUserItem[wChairID].dwUserID, sData);
				} else {
					Replay.AddJsonMsg(wChairID, sData);
					// mPlayers[wChairID].SendGameMessage(wSubCmdID, pData,
					// wDataSize, data);
				}
				return true;
			}
		}

		return false;
	}

	void FaPai() {
		/**
		 * 开局清除上一局碰杠牌的信息
		 */
		userGangInfos.clear();
		userPongInfos.clear();
		ZuoPai();
		// m_byRound局数 m_byMaxRound最大局数
		if (m_byRound > m_byMaxRound) {
			return;
		}

		m_byRound = (m_byRound + 1);
		OnRoundInfoChange();
		Replay.SetIndexJushu(m_byRound);
		SUBCMD_S_FaPai cmd = new SUBCMD_S_FaPai();
		// Constants.memset(cmd,0,Constants.sizeof(cmd));
		cmd.byRound = m_byRound;
		// 用于显示庄的位置
		cmd.byZhuang = m_byZhuang;
		cmd.lastZhuang = lastZhuang;
		// 用于显示连庄的位置
		cmd.byLianZhuang = m_byLianZhuang;
		cmd.byMaxRound = m_byMaxRound;
		/**
		 * 鬼牌就叫财神
		 */
		cmd.byGuiPai[0] = m_caiShen;
		cmd.byGuiPai[1] = 255;
		/**
		 * 翻牌
		 */
		cmd.fanPai = fan_caiShen;
		for (int i = 0; i < 4; i++) {
			MajSide lMajSide = m_MajLogic.GetMajSide(i);
			lMajSide.SortCard();

			Constants.memcpy(cmd.byMj, lMajSide.Maj, 14);

			String sData = cmd.getJsonData();
			if (m_pIUserItem[i].isAndroidUser == 0) {
				SendData(m_pIUserItem[i].dwUserID, sData);
				m_wDealErrorDelay = 0;
			}
		}
		// ((dthall*)m_objAppHandler).onSendXLCH(_Uid,(char*)sData,sData.size());

	}

	void Test() {

	}

	void TestRoundEnd() {
		m_MajLogic.SetCurrentUser(0);
		m_byZhuang = 0;
		m_bTianHu = true;
		MajSide l_MajSide = m_MajLogic.m_kPaiJu.MajSides[0];
		l_MajSide.Init();
		int Maj[][] = { { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 8, 6 },
				{ 9, 10, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 17, 10 },
				{ 18, 19, 19, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 26, 19 },
				{ 0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 0 },
				{ 9, 9, 9, 10, 11, 11, 12, 13, 13, 14, 15, 16, 16, 17, 17, 17, 9 },
				{ 18, 20, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 26, 26, 26, 26, 18 },
				{ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 0 },
				{ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 9 },
				{ 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 18 },
				{ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 4, 5, 6, 8, 8 },
				{ 0, 0, 1, 2, 3, 5, 5, 6, 7, 8, 8, 8, 8, 30, 30, 30, 0 },
				{ 9, 9, 10, 11, 12, 13, 13, 14, 15, 16, 16, 16, 16, 27, 27, 27, 9 },
				{ 18, 18, 19, 20, 21, 22, 22, 23, 24, 25, 25, 25, 25, 28, 28, 28, 18 },
				{ 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 29, 29, 32, 32, 29 },
				{ 9, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 28, 28, 31, 31, 28 },
				{ 18, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 32, 32, 33, 33, 32 },
				{ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 27, 27, 27, 0 },
				{ 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, 17, 28, 28, 28, 9 },
				{ 18, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 27, 27, 27, 18 },
				{ 0, 1, 6, 7, 8, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 2 },
				{ 9, 10, 15, 16, 17, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 11 },
				{ 18, 19, 24, 25, 26, 27, 27, 28, 28, 28, 30, 30, 30, 31, 31, 31, 20 },
				{ 0, 2, 6, 7, 8, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 1 },
				{ 9, 11, 15, 16, 17, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 10 },
				{ 18, 20, 24, 25, 26, 27, 27, 28, 28, 28, 30, 30, 30, 31, 31, 31, 19 },
				{ 2, 2, 2, 3, 3, 3, 12, 12, 12, 19, 19, 21, 21, 33, 33, 33, 19 },
				{ 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 12 },
				{ 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 22, 22, 22 },
				{ 0, 0, 0, 2, 2, 2, 4, 6, 6, 6, 15, 15, 15, 16, 16, 16, 3 },
				{ 1, 1, 5, 6, 7, 10, 11, 12, 15, 17, 22, 22, 22, 23, 24, 25, 16 },
				{ 0, 1, 2, 9, 11, 29, 29, 29, 31, 31, 31, 32, 32, 32, 33, 33, 10 },
				{ 27, 27, 27, 28, 28, 28, 29, 31, 31, 31, 32, 32, 32, 33, 33, 33, 29 },
				{ 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 32, 32, 32, 33, 33 },
				{ 14, 14, 14, 16, 17, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 15 },
				{ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 18, 18, 20, 20, 18 },
				{ 0, 1, 2, 9, 10, 11, 12, 13, 14, 18, 19, 20, 21, 22, 24, 24, 20 },
				{ 1, 2, 3, 4, 5, 6, 15, 16, 18, 19, 20, 21, 22, 23, 25, 25, 14 },
				{ 0, 1, 2, 9, 10, 11, 14, 14, 19, 20, 21, 22, 23, 24, 26, 26, 14 },
				{ 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 11, 11, 11, 18, 19, 20, 1 },
				{ 2, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 8, 8, 8, 2 },
				{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 19, 20, 26, 32 },
				{ 0, 1, 2, 9, 9, 10, 11, 12, 12, 13, 18, 19, 20, 27, 27, 27, 11 },
				{ 0, 0, 12, 13, 14, 15, 16, 23, 24, 24, 25, 25, 26, 29, 29, 29, 17 }

		};

		byTestIndex = 42;// byTestIndex % 42; //
		m_MajLogic.SetLastOutMj(Maj[byTestIndex][Constants.HAND_MJ_MAX - 1]);
		Constants.memcpy(l_MajSide.Maj, Maj[byTestIndex], Constants.HAND_MJ_MAX);
		m_byRight[0][4] = 1; //
		m_bTianHu = false; //
		// OnUserHu(0, null); //
		byTestIndex++;
	}

	static int byTestIndex = 0;

	void PrintPai() {
	}

	void CleanTempAction() {
		for (int i = 0; i < 4; i++) {
			m_tempAction[i].Clean();
		}
	}

	void CleanTempRight(int bySeatID) {

		if (bySeatID >= 0 && bySeatID < 4) {
			m_byRight[bySeatID][0] = 0;
			m_byRight[bySeatID][1] = 0;
			m_byRight[bySeatID][2] = 0;
			m_byRight[bySeatID][3] = 0;
			m_byRight[bySeatID][4] = 0;
			m_byRight[bySeatID][5] = 0;
		}
	}

	void CleanQiangGangHuRight(int bySeatID) {
		if (bySeatID >= 0 && bySeatID < 4) {
			m_bQiangGangHu[bySeatID] = false;
		}
		if (bySeatID == Constants.INVALID_CHAIR) {
			m_bQiangGangHu[0] = false;
			m_bQiangGangHu[1] = false;
			m_bQiangGangHu[2] = false;
			m_bQiangGangHu[3] = false;
		}
	}

	void ZuoPai() {
		m_MajPaiQiang.PaiWei = m_nMaxMaPai;
		m_MajPaiQiang.Ruffle(1500);
		m_MajLogic.Init(Constants.INIT_NEWROUND);
		m_MajLogic.GetMajSide(0).Maj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;
		m_MajLogic.GetMajSide(1).Maj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;
		m_MajLogic.GetMajSide(2).Maj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;
		m_MajLogic.GetMajSide(3).Maj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;

		// fan_caiShen代表翻得那张牌用于传到前台
		fan_caiShen = m_MajPaiQiang.GetGuiPai();
		if (fan_caiShen == 36) {
			fan_caiShen = 35;
		}
		// 获取宝牌，随便配
		m_caiShen = fan_caiShen + 1;
		// 宝牌顺序进行循环，东西南北单循环 中发白单循环
		if (fan_caiShen == 9) {
			m_caiShen = 1;
		}
		if (fan_caiShen == 19) {
			m_caiShen = 11;
		}
		if (fan_caiShen == 29) {
			m_caiShen = 21;
		}
		if (fan_caiShen == 34) {
			m_caiShen = 31;
		}
		if (fan_caiShen == 37) {
			m_caiShen = 35;
		}

		// m_caiShen = 34;
		int test26[] = { 11, 11, 11, 12, 13, 14, 16, 15, 27, 28, 29, 33, 33 };
		int test27[] = { 1, 4, 7, 11, 14, 17, 31, 32, 33, 34, 35, 36, 37 };
		int test28[] = { 18, 18, 5, 5, 5, 5, 18, 18, 24, 24, 28, 28, 29 };
		int test29[] = { 31, 31, 31, 33, 33, 33, 12, 12, 12, m_caiShen, m_caiShen, m_caiShen, m_caiShen };

		for (int by = 0; by < Constants.HAND_MJ_MAX - 1; by++) {
			//m_MajLogic.GetMajSide(0).Maj[by] = test29[by];
			// m_MajLogic.GetMajSide(1).Maj[by]=test67[by];
			// m_MajLogic.GetMajSide(2).Maj[by]=test68[by];
			// m_MajLogic.GetMajSide(3).Maj[by]=test60[by];
			m_MajLogic.GetMajSide(0).Maj[by] = m_MajPaiQiang.GetPai();
			m_MajLogic.GetMajSide(1).Maj[by] = m_MajPaiQiang.GetPai();
			m_MajLogic.GetMajSide(2).Maj[by] = m_MajPaiQiang.GetPai();
			m_MajLogic.GetMajSide(3).Maj[by] = m_MajPaiQiang.GetPai();
			if (l_seat != -1) {
				m_MajLogic.GetMajSide(l_seat).Maj[by] = l_handMj[by];
			}
		}
		l_seat = -1;
		// 0, 1, 2, 3, 4, 5, 6, 7, 8, // 0-8 一万-九万
		// 9, 10, 11, 12, 13, 14, 15, 16, 17, // 9-17 一筒-九筒
		// 18, 19, 20, 21, 22, 23, 24, 25, 26, // 18-26 一条-九条

	}

	int GetActionRight(int bySeatID) {
		if (m_byRight[bySeatID][4] > 0) {
			return Constants.ACTION_HU;
		}
		if (m_byRight[bySeatID][2] > 0) {
			return Constants.ACTION_GANG;
		}
		if (m_byRight[bySeatID][1] > 0) {
			return Constants.ACTION_PENG;
		}
		if (m_byRight[bySeatID][0] > 0) {
			return Constants.ACTION_CHI;
		}
		return 0;
	}

	boolean HasQiangGangHuRight() {

		for (int i = 0; i < 4; i++) {
			if (m_bQiangGangHu[i]) {
				return true;
			}
		}

		return false;
	}

	boolean IsAllowDianPaoHu(int bySeatID, int byOutMj, int byTestSeatID) {

		if (m_bIsAllowHu[byTestSeatID]) {
			MajSide l_MajSide = m_MajLogic.GetMajSide(byTestSeatID);
			if (byOutMj == l_MajSide.byLastOutMj) {
				return false;
			}
		}
		return m_bIsAllowHu[byTestSeatID];
	}

	// 用户出牌
	boolean OnUserOutMj(int bySeatID, int byOutMj) {
		System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj 0: " + bySeatID + "-" + byOutMj);
		if (bySeatID >= 4 || !MajHelper.IsWTSZ(byOutMj)) {
			System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj return false 1 ");
			return false;
		}
		if (m_bGameStarted == false) {
			System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj return false 2 ");
			return false;
		}
		if (byOutMj == m_caiShen) {//记录打宝牌
			for (int i = 0; i < 4; i++) {
				if (outMjs[bySeatID][i] == 0) {
					outMjs[bySeatID][i] = byOutMj;
					break;
				}
			}
		}

		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);

		m_wRobotSeconds[bySeatID] = 0L;
		if ((l_MajSide.GetHandMjCount() % 3) != 2) {
			System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj return false 3 " + "-"
					+ IJsonExport.sprintf_INT32(l_MajSide.Maj, 14));
			return false;
		}
		if (GetActionRight(bySeatID) == Constants.ACTION_HU) {
			m_bIsAllowHu[bySeatID] = false;
		}
		if (m_bIsGang[bySeatID] == true) {
			m_bIsGang[bySeatID] = false;
		}
		CleanTempRight(bySeatID);
		CleanQiangGangHuRight(Constants.INVALID_CHAIR);
		// m_MajLogic.GetMajSide(bySeatID).SetMoPai(byOutMj);

		System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj 1: " + bySeatID + "-" + byOutMj + "-"
				+ IJsonExport.sprintf_INT32(l_MajSide.Maj, 14));
		m_MajLogic.SetCurrentAction(0);

		// 天胡
		if (m_bTianHu) {// 有人出过牌就不可能是天胡了
			m_bTianHu = false;
		}
		// 庄家以外出牌，人和否定
		if (m_bRenHu[bySeatID] && m_byChuPaiCount[bySeatID] >= 1) {
			m_bRenHu[bySeatID] = false;
		}
		if (m_bDiHu[bySeatID]) {// 在第一圈内 闲家胡 意思是没出过牌?
			m_bDiHu[bySeatID] = false;
		}
		if (bySeatID != m_byZhuang) {// 非庄出牌 开局后，庄家打出的第一张牌放铳给闲家胡的牌。
			for (int i = 0; i < 4; i++) {
				m_bDiHu[i] = false;
			}
		}

		m_byChuPaiCount[bySeatID]++;
		if (bySeatID == m_byZhuang && m_byChuPaiCount[bySeatID] == 1) {
			// 庄出第一张牌
		}

		// 取消操作权
		if (GetActionRight(bySeatID) > 0) {
			CleanTempRight(bySeatID);
		}

		// 牌值校验
		for (int byIndex = 0; byIndex < Constants.HAND_MJ_MAX; byIndex++) {
			if (l_MajSide.Maj[byIndex] == byOutMj) {
				// 有效删除麻将
				l_MajSide.Maj[byIndex] = Constants.INVALID_CARD;

				l_MajSide.ChuPai(byOutMj);

				l_MajSide.SortCard(Constants.HAND_MJ_MAX);

				break;
			}
		}

		m_MajLogic.SetCurrentUser(bySeatID);
		m_MajLogic.SetLastOutMj(byOutMj);

		// 发送数据结构
		SUBCMD_S_ChuPai cmd = new SUBCMD_S_ChuPai();
		cmd.byActionUser = bySeatID;
		cmd.byOutMj = byOutMj;

		// 发送数据
		for (int byIndex = 0; byIndex < 4; byIndex++) {
			cmd.bHu = 0;
			cmd.bGang = 0;
			cmd.bPeng = 0;
			cmd.bChi = 0;

			MajSide l_MajSideTmp = m_MajLogic.GetMajSide(byIndex);

			if (bySeatID != byIndex) {
				if (byOutMj != m_caiShen) {
					ArrayList<HU> list = new ArrayList<HU>();
					// cmd.bHu = (MajHelper.HongZongTibaoHu(l_MajSideTmp.Maj,
					// byOutMj, l_MajSideTmp.hu, m_caiShen, false,
					// list) ? 1 : 0);
				}

				// if (m_hutype == 1) {
				// cmd.bHu = 0;
				// }
				if (m_bTing[byIndex] == false) {
					// 調用杠的方法，GangStyle代表杠的種類
					// 第一個參數代表手中的牌，第二個參數代表別人出的牌
					cmd.bGang = MajHelper.IsGang(l_MajSideTmp.Maj, byOutMj).GangStyle;
					cmd.bPeng = (MajHelper.IsPeng(l_MajSideTmp.Maj, byOutMj, m_caiShen) ? 1 : 0);
					cmd.bChi = 0;
				} else {
					cmd.bGang = 0;
					cmd.bPeng = 0;
					cmd.bChi = 0;
				}
				// 操作权限
				if (m_bTing[byIndex] == false) {

					if (cmd.bChi != 0) {
						m_byRight[byIndex][0] = 1;
					}
					if (cmd.bPeng != 0) {
						m_byRight[byIndex][1] = 1;
					}
					if (cmd.bGang != 0) {
						m_byRight[byIndex][2] = 1;
					}
				}
				if (cmd.bHu != 0) {
					m_byRight[byIndex][4] = 1;
				}

			}

			m_MajLogic.m_byOutMjCount++;

			m_byRight[byIndex][0] = cmd.bChi;
			m_byRight[byIndex][1] = cmd.bPeng;
			m_byRight[byIndex][2] = cmd.bGang;
			m_byRight[byIndex][3] = 0;
			m_byRight[byIndex][4] = cmd.bHu;

			Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
			if (byIndex == bySeatID) {
				Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
			} else {
				Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
				for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
					if (cmd.byHandMj[k] != Constants.INVALID_CARD) {
						cmd.byHandMj[k] = 99;
					}
				}
			}

			if (byOutMj == m_caiShen) {
				cmd.bGang = 0;
				cmd.bPeng = 0;
				cmd.bChi = 0;
				cmd.bHu = 0;

				CleanTempRight(0);
				CleanTempRight(1);
				CleanTempRight(2);
				CleanTempRight(3);
			}

			if (m_qiuPaiNum[byIndex][bySeatID] >= 2) {
				cmd.bGang = 0;
				cmd.bPeng = 0;
				cmd.bChi = 0;

				m_byRight[byIndex][0] = cmd.bChi;
				m_byRight[byIndex][1] = cmd.bPeng;
				m_byRight[byIndex][2] = cmd.bGang;
			}
			String sData = cmd.getJsonData();
			SendData(m_pIUserItem[byIndex].dwUserID, sData);
			m_wDealErrorDelay = 0;
		}
		CleanTempAction();

		m_MajLogic.SetLastUser(bySeatID);
		// 无人有操作,下家摸牌
		for (int j = 0; j < 4; j++) {
			if (GetActionRight(j) != 0)
				break;
			else {
				// 无人有吃碰杠胡
				if (j == 3) {
					// 切换用户

					m_MajLogic.SetCurrentUser(MajHelper.GetNextUser(bySeatID));

					OnUserTouchMj(m_MajLogic.GetCurrentUser());
				}
			}
		}

		return true;
	}

	int random(int iMin, int iMax) {
		Random ra = new Random();
		return ra.nextInt(iMax - iMin) + iMin;
	}

	boolean isCanMoPai(int bySeatID) {
		boolean bNeedWait = false;
		for (int i = 0; i < 4; i++) {
			if (GetActionRight(i) > 0) {
				bNeedWait = true;
			}
		}
		if (bNeedWait) {
			return false;
		}
		for (int i = 0; i < 4; i++) {
			MajSide tmp_MajSide = m_MajLogic.GetMajSide(i);
			if (tmp_MajSide.GetHandMjCount() % 3 != 1) {
				bNeedWait = true;
			}
		}
		if (bNeedWait) {
			return false;
		}

		// if(m_MajLogic.GetCurrentUser() != bySeatID &&
		// MajHelper.GetNextUser(m_MajLogic.GetCurrentUser()) != bySeatID)
		{
			// return false;
		}
		return true;
	}

	void OnMJMsg(int seat, int pai) {
		seatId = seat;
		nextPai = pai;
	}

	void OnZuoMj(int seat, int pai[]) {
		l_seat = seat;
		for (int i = 0; i < pai.length; i++) {
			l_handMj[i] = pai[i];
		}
	}

	// 用户摸牌
	boolean OnUserTouchMj(int bySeatID) {
		return OnUserTouchMj(bySeatID, 0);
	}

	int cnt_step = 0;

	boolean OnUserTouchMj(int bySeatID, int cbReason) {
		System.out.println("[" + m_dwTableID + "] " + "OnUserTouchMj 0: " + bySeatID);
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}

		if (isCanMoPai(bySeatID) == false) {
			return false;
		}
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		if ((l_MajSide.GetHandMjCount() % 3) != 1) {
			System.out.println("[" + m_dwTableID + "] " + "OnUserTouchMj return false  " + bySeatID);
			return false;
		}
		// 血流成河独特玩法
		if (m_MajPaiQiang.IsEnd() != 0) {
			m_byLianZhuang++;
			OnEventGameEnd(bySeatID, Constants.GAME_END_PASS);
			return false;
		}
		CleanQiangGangHuRight(Constants.INVALID_CHAIR);

		SUBCMD_S_MoPai cmd = new SUBCMD_S_MoPai();
		cmd.reason = cbReason;
		cmd.bySeatID = bySeatID;

		// 设置成当前玩家
		m_MajLogic.SetCurrentUser(bySeatID);

		int byMoPai = Constants.INVALID_CARD;
		// cbReason代表摸牌的几种情况
		switch (cbReason) {
		// 杠后摸牌
		case Constants.ACTION_GANG_BUPAI:
			if (nextPai != 0 && bySeatID == seatId) {
				byMoPai = m_MajPaiQiang.GetZdPai(bySeatID, nextPai);
				m_bIsGang[bySeatID] = true;
				nextPai = 0;
				seatId = -1;// 重置 只获取一次指定牌
			} else {
				byMoPai = m_MajPaiQiang.GetGangMoPai();
				m_bIsGang[bySeatID] = true;
			}
			break;
		// 花摸牌
		case Constants.ACTION_BU_HUA:
			byMoPai = m_MajPaiQiang.GetBuHuaMoPai();
			break;
		// 正常的摸牌
		default:
			if (nextPai != 0 && bySeatID == seatId) {
				byMoPai = m_MajPaiQiang.GetZdPai(bySeatID, nextPai);
				nextPai = 0;
				seatId = -1;// 重置 只获取一次指定牌
			} else {
				byMoPai = m_MajPaiQiang.GetPai();
			}
			break;
		}

		MJ_Action action = new MJ_Action();
		action.m_Action = Constants.ACTION_MO_PAI;

		action.bySeatID = bySeatID;
		action.m_cMoPai.byMj = byMoPai;
		m_history.add(action);

		m_bIsAllowHu[bySeatID] = true;

		System.out.println("[" + m_dwTableID + "] " + "OnUserTouchMj 1: " + bySeatID + "-" + byMoPai);

		if (!MajHelper.IsWTSZ(byMoPai)) {
			OnEventGameEnd(bySeatID, Constants.GAME_END_PASS);
			return true;
		}
		for (int byIndex = 0; byIndex < 4; byIndex++) {
			Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
			if (byIndex == bySeatID) {
				cmd.byMoPai = byMoPai;
				// 胡、杠牌判断
				// 自摸
				MajSide l_TmpMajSide = m_MajLogic.GetMajSide(byIndex);

				l_TmpMajSide.SetMoPai(byMoPai);
				int byTempMj[] = new int[Constants.HAND_MJ_MAX];
				Constants.memcpy(byTempMj, l_TmpMajSide.Maj, Constants.HAND_MJ_MAX);
				// 对手里的牌进行排序
				MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX);

				ArrayList<HU> list = new ArrayList<HU>();
				cmd.nHu = (MajHelper.HongZongTibaoHu(byTempMj, Constants.INVALID_CARD, l_TmpMajSide.hu, m_caiShen, true,
						list,m_siBao) ? 1 : 0);

				if (m_bTing[bySeatID] == true) {
					/*
					 * for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++)
					 * { if (l_TmpMajSide.hu.block[i].style ==
					 * Constants.BLOCK_PENG) { if
					 * (l_TmpMajSide.hu.block[i].first == byMoPai) { cmd.nGang =
					 * 2; break; } } }
					 */

					MJ_GANGINFO mjAnGang1 = MajHelper.IsAnGang(byTempMj);
					MJ_GANGINFO mjAnGang = new MJ_GANGINFO();
					mjAnGang.GangMj = Constants.INVALID_CARD;
					mjAnGang.GangStyle = 0;
					MJ_GANGINFO mjAnGang2 = MajHelper.IsAnGang(byTempMj, mjAnGang1.GangMj);
					MJ_GANGINFO mjAnGang3 = MajHelper.IsAnGang(byTempMj, mjAnGang1.GangMj, mjAnGang2.GangMj);
					MJ_GANGINFO mjAnGang4 = MajHelper.IsAnGang(byTempMj, mjAnGang1.GangMj, mjAnGang2.GangMj,
							mjAnGang3.GangMj);
					if (mjAnGang1.GangMj == byMoPai) {
						mjAnGang = mjAnGang1;
					}
					if (mjAnGang2.GangMj == byMoPai) {
						mjAnGang = mjAnGang2;
					}
					if (mjAnGang3.GangMj == byMoPai) {
						mjAnGang = mjAnGang3;
					}
					if (mjAnGang4.GangMj == byMoPai) {
						mjAnGang = mjAnGang4;
					}
					if (mjAnGang.GangMj != Constants.INVALID_CARD)

						if (mjAnGang1.GangStyle != 0) {
							int byTingPai[] = new int[42];
							int byEmptyHua[] = new int[8];
							int oldTingPaiCount = MajHelper.GetTingPai(l_TmpMajSide.Maj, l_TmpMajSide.hu, byEmptyHua,
									byTingPai, m_caiShen,m_siBao);
							int byTestGangMj[] = new int[Constants.HAND_MJ_MAX];
							HU testGangHu = l_TmpMajSide.hu;
							Constants.memcpy(byTestGangMj, byTempMj, Constants.HAND_MJ_MAX);
							BLOCK gangBlock = MajHelper.AnGang(byTestGangMj, mjAnGang.GangMj);

							MajHelper.AddBlock(testGangHu, gangBlock);
							MajHelper.SortCard(byTestGangMj, Constants.HAND_MJ_MAX);
							int newTingPaiCount = MajHelper.GetTingPai(byTestGangMj, testGangHu, byEmptyHua, byTingPai,
									m_caiShen,m_siBao);
							if (newTingPaiCount >= oldTingPaiCount) {
								cmd.nGang = (cmd.nGang + 4);
							}
						}
				} else {
					MJ_GANGINFO mjAnGang = MajHelper.IsAnGang(byTempMj);

					MJ_GANGINFO mjZMGang = MajHelper.IsZMGang(byTempMj, l_TmpMajSide.hu);
					cmd.nGang = (mjAnGang.GangStyle + mjZMGang.GangStyle);
				}
				if (cmd.nHu > 0) {
					cmd.nQiaoXiangHu = 0;
				}
			} else {
				cmd.nGang = 0;
				cmd.nHu = 0;
				cmd.byMoPai = 255;
				if (MajHelper.IsHuaPai(byMoPai)) {
					cmd.byMoPai = byMoPai;
				} else {
					cmd.byMoPai = 99;
				}
			}
			m_byRight[byIndex][0] = 0;
			m_byRight[byIndex][1] = 0;
			m_byRight[byIndex][2] = cmd.nGang > 0 ? 1 : 0;
			m_byRight[byIndex][3] = cmd.bTing;
			m_byRight[byIndex][4] = cmd.nHu;
			Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
			if (byIndex == bySeatID) {
				Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
			} else {
				Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
				for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
					if (cmd.byHandMj[k] != Constants.INVALID_CARD) {
						cmd.byHandMj[k] = 99;
					}
				}
				cmd.byHandMj[Constants.HAND_MJ_MAX - 1] = 99;
			}

			String sData = cmd.getJsonData();
			SendData(m_pIUserItem[byIndex].dwUserID, sData);
			m_wDealErrorDelay = 0;
		}

		SendYuPai();
		return true;
	}

	boolean OnUserBuHua(int bySeatID) {
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		m_MajLogic.SetCurrentAction(Constants.ACTION_BU_HUA);
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		int byMoPai = l_MajSide.GetMoPai();
		if (MajHelper.IsHuaPai(byMoPai)) {
			l_MajSide.AddHua(byMoPai);
			l_MajSide.SetMoPai(Constants.INVALID_CARD);
			OnUserTouchMj(bySeatID, Constants.ACTION_BU_HUA);
			m_wDealErrorDelay = 0;
		} else {

		}
		return true;
	}

	// 用户放弃
	boolean OnUserGiveUp(int bySeatID, SUBCMD_C_Operation Operation) {
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		if (GetActionRight(bySeatID) == Constants.ACTION_HU) {
			m_bIsAllowHu[bySeatID] = false;
		}

		m_MajLogic.SetCurrentAction(Constants.ACTION_GIVE_UP);
		// 变量定义

		CleanTempRight(bySeatID);
		boolean bHasQiangGangHu = HasQiangGangHuRight();
		CleanQiangGangHuRight(bySeatID);

		if (m_bGameStarted) {
			for (int k = 0; k < 4; k++) {
				if (m_bIsHu[k]) {
					int cntHuRight = 0; // 操作者数
					for (int i = 0; i < 4; i++) {
						// 跳过自已,和出牌者
						if (GetActionRight(i) == Constants.ACTION_HU) {

							cntHuRight++;
							break;
						}
					}
					if (cntHuRight == 0) {
						CleanTempAction();

						OnEventGameEnd(bySeatID, Constants.GAME_END_NORMAL);
						m_wDealErrorDelay = 0;
					}
				}
			}
		}

		// 非当前玩家
		if (m_MajLogic.GetMajSide(bySeatID).Maj[Constants.HAND_MJ_MAX - 1] == Constants.INVALID_CARD) {
			int tempRight = 0;
			for (int i = 0; i < 4; i++) {
				if (GetActionRight(i) > tempRight) {
					tempRight = GetActionRight(i);
				}
			}
			if (tempRight > 0) {
				int bySeat1 = MajHelper.GetNextUser(m_MajLogic.GetCurrentUser());
				int bySeat2 = MajHelper.GetNextUser(bySeat1);
				int bySeat3 = MajHelper.GetNextUser(bySeat2);

				int bySeatOrder[] = new int[4];
				bySeatOrder[0] = m_MajLogic.GetCurrentUser();
				bySeatOrder[1] = bySeat1;
				bySeatOrder[2] = bySeat2;
				bySeatOrder[3] = bySeat3;
				for (int i = 0; i < 4; i++) {
					if (bySeatOrder[i] == bySeatID || bySeatOrder[i] == m_MajLogic.GetCurrentUser())
						continue;
					switch (m_tempAction[bySeatOrder[i]].m_ActionRight) {
					case Constants.ACTION_CHI:
						OnUserChi(bySeatOrder[i], m_tempAction[bySeatOrder[i]].m_cChi);
						// CleanTempAction();
						break;
					case Constants.ACTION_PENG:
						OnUserPeng(bySeatOrder[i], m_tempAction[bySeatOrder[i]].m_cPeng);
						// CleanTempAction();
						break;
					case Constants.ACTION_GANG:
						OnUserGang(bySeatOrder[i], m_tempAction[bySeatOrder[i]].m_cGang);
						// CleanTempAction();
						break;
					case Constants.ACTION_HU:
						OnUserHu(bySeatOrder[i], m_tempAction[bySeatOrder[i]].m_cHu, 1);
						// CleanTempAction();
						break;
					default:
						break;
					}
				}
			} else {
				// 全部人都放弃操作,下家摸牌
				if (bHasQiangGangHu) {
					m_isBusy = true;
					OnUserTouchMj(m_MajLogic.GetCurrentUser(), 0);
					m_isBusy = false;
				} else {
					int byNextUser = MajHelper.GetNextUser(m_MajLogic.GetCurrentUser());
					m_isBusy = true;
					OnUserTouchMj(byNextUser, 0);
					m_isBusy = false;
				}

			}
		}

		return true;
	}

	// 用户碰牌
	boolean OnUserPeng(int bySeatID, SUBCMD_C_Operation Peng) {
		if (bySeatID >= 4 || Peng == null) {
			return false;
		}

		// if (m_qiuPaiNum[bySeatID][m_MajLogic.GetCurrentUser()] >= 2) {
		// return false;// 不能三吃
		// }
		{
			MajSide l_MajSide0 = m_MajLogic.GetMajSide(bySeatID);
			System.out.println("[" + m_dwTableID + "] " + "OnUserPeng 2 :" + bySeatID + ":"
					+ IJsonExport.sprintf_INT32(l_MajSide0.Maj, 14));
		}
		int byChuPaiUser = m_MajLogic.GetCurrentUser();
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		MajSide l_ChuPaiMajSide = m_MajLogic.GetMajSide(byChuPaiUser);

		if ((l_MajSide.GetHandMjCount() % 3) != 1) {
			return false;
		}
		m_MajLogic.SetCurrentAction(Constants.ACTION_PENG);
		// 权限效验
		if (GetActionRight(bySeatID) < Constants.ACTION_PENG) {
			return false;
		}
		for (int i = 0; i < 4; i++) {
			m_bDiHu[i] = false;
		}
		int byLastOutMj = m_MajLogic.GetLastOutMj();
		int byLastOutUser = m_MajLogic.GetCurrentUser();

		MJ_Action action = new MJ_Action();
		action.m_Action = Constants.ACTION_PENG;

		action.bySeatID = bySeatID;
		action.m_cPeng.byMj = byLastOutMj;
		m_history.add(action);

		BLOCK_PONGINFO pongInfo = new BLOCK_PONGINFO();
		pongInfo.PongUser = bySeatID;
		pongInfo.first = byLastOutMj;
		pongInfo.dianPongUser = byLastOutUser;
		pongInfosOf(pongInfo.PongUser).add(pongInfo);

		for (int i = 0; i < 4; i++) {
			int byNextUser1 = MajHelper.GetNextUser(byChuPaiUser);
			int byNextUser2 = MajHelper.GetNextUser(byNextUser1);
			int byNextUser3 = MajHelper.GetNextUser(byNextUser2);
			if (bySeatID == byNextUser2) {
				m_bIsAllowHu[byNextUser1] = true;
			}
			if (bySeatID == byNextUser3) {
				m_bIsAllowHu[byNextUser1] = true;
				m_bIsAllowHu[byNextUser2] = true;
			}
		}

		// 无碰操作权限以上的操作
		int userCount = 0; // 操作者数
		for (int i = 0; i < 4; i++) {
			// 跳过自已,和出牌者
			if (i == bySeatID || i == m_MajLogic.GetCurrentUser())
				continue;

			if (GetActionRight(i) > Constants.ACTION_PENG) {
				m_tempAction[bySeatID].m_ActionRight = Constants.ACTION_PENG;
				m_tempAction[bySeatID].m_cPeng = Peng;
				CleanTempRight(bySeatID);
				m_byRight[bySeatID][1] = 1;
				break;
			} else {
				userCount++;
				CleanTempRight(i);
				if (userCount == 2) {
					CleanTempRight(bySeatID);
					CleanTempAction();
					// 处理碰
					MJ_BLOCK block;
					block = (MJ_BLOCK) MajHelper.Peng(l_MajSide.Maj, m_MajLogic.GetLastOutMj(), m_caiShen);
					block.origValue = MajHelper.GetRelativeSeat(bySeatID, byLastOutUser);
					MajHelper.AddBlock(l_MajSide.hu, block);
					// m_MajLogic.GetMajSide(bySeatID).SortCard();
					MajHelper.SortCard(l_MajSide.Maj, Constants.HAND_MJ_MAX);
					// 发送消息
					SUBCMD_S_Peng cmd = new SUBCMD_S_Peng();
					cmd.block.first = block.first;
					cmd.block.style = block.style;
					cmd.block.origValue = block.origValue;
					cmd.byActionUser = bySeatID;
					cmd.byMj = byLastOutMj;
					cmd.byOutMjUser = byLastOutUser;// m_MajLogic.GetCurrentUser();
					if (true) {
						int byTempMj[] = new int[Constants.HAND_MJ_MAX];
						Constants.memcpy(byTempMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX);
						MJ_GANGINFO mjAnGang = MajHelper.IsAnGang(byTempMj);
						MJ_GANGINFO mjZMGang = MajHelper.IsZMGang(byTempMj, l_MajSide.hu);
						cmd.canGang = (mjAnGang.GangStyle + mjZMGang.GangStyle);
						if (cmd.canGang > 0) {
							m_byRight[bySeatID][2] = 1;
						}
					}

					l_ChuPaiMajSide.BeiChiPai();
					m_qiuPaiNum[bySeatID][m_MajLogic.GetCurrentUser()]++;// 吃碰牌数量
					// 当前用户变换
					m_MajLogic.SetCurrentUser(bySeatID);
					for (int j = 0; j < 4; j++) {
						Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
						if (j == bySeatID) {
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						} else {
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
								if (cmd.byHandMj[k] != Constants.INVALID_CARD) {
									cmd.byHandMj[k] = 99;
								}
							}
						}
						String sData = cmd.getJsonData();
						SendData(m_pIUserItem[j].dwUserID, sData);
						m_wDealErrorDelay = 0;
					}
					break;
				}
			}
		}
		SendYuPai();
		return true;
	}

	void Handle_onYiPaoSanXiangHu(int seatId) {
		int huCount = 0;
		for (int i = 0; i < 4; i++) {
			if (this.m_roundHuSeated[i] >= 0) {
				huCount++;
			}
		}
		if (huCount == 0) {
			// 一炮三响的玩家选择了全部过,继续摸牌
			clearRoundHu();
			SUBCMD_C_Operation guo = new SUBCMD_C_Operation();
			m_isBusy = true;
			OnUserGiveUp(seatId, guo);
			m_isBusy = false;
		} else {
			// 这时候一定是顺序胡牌的
			if (huCount == 1)
				m_hasYiPaoSanXiang = false;
			else
				m_hasYiPaoSanXiang = true;
			int huindex = 0;
			for (int i = 0; i < 4; i++) {
				if (this.m_roundHuSeated[i] >= 0) {
					huindex++;
					SUBCMD_C_Hu hu = new SUBCMD_C_Hu();
					OnUserHu(this.m_roundHuSeated[i], hu, huindex == huCount ? 1 : 0);
				}
			}
		}
	}

	// 赢的那个人座位的bySeatID
	boolean OnUserHu(int bySeatID, SUBCMD_C_Hu hu, int huindex) {
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		// 当前玩家
		int byLastOutUser = m_MajLogic.GetCurrentUser();
		// 权限效验 ACTION_HU = 8;
		if (GetActionRight(bySeatID) < Constants.ACTION_HU && m_byRight[bySeatID][4] == 0) {
			return false;
		}
		int byNextUser1 = MajHelper.GetNextUser(byLastOutUser);
		int byNextUser2 = MajHelper.GetNextUser(byNextUser1);
		int byNextUser3 = MajHelper.GetNextUser(byNextUser2);
		if (bySeatID == byNextUser1) {

		}
		if (bySeatID == byNextUser2 && GetActionRight(byNextUser1) == Constants.ACTION_HU) {
			return false;
		}
		if (bySeatID == byNextUser3 && (GetActionRight(byNextUser1) == Constants.ACTION_HU
				|| GetActionRight(byNextUser2) == Constants.ACTION_HU)) {
			return false;
		}
		HU temphu = new HU();
		MajHelper.CleanHu(temphu);
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		l_MajSide.SortCard();
		int byActivePai = (bySeatID == byLastOutUser) ? l_MajSide.GetMoPai() : m_MajLogic.GetLastOutMj();

		ArrayList<HU> list = new ArrayList<HU>();

		boolean bZiMo = false;
		boolean bCengBao = false;
		if (bySeatID == byLastOutUser) // 自摸一台
		{
			bZiMo = true;
		}
		// 普通胡法，不包括红中替宝胡

		boolean IsHu = MajHelper.IsHu(l_MajSide.Maj, byActivePai, l_MajSide.hu, m_caiShen, bZiMo, list,m_siBao);
		boolean hongZhongTiBaoHu = false;
		if (!IsHu) {
			// 红中替宝胡
			list.clear();
			hongZhongTiBaoHu = MajHelper.HongZongTibaoHu(l_MajSide.Maj, byActivePai, l_MajSide.hu, m_caiShen, bZiMo,
					list,m_siBao);
			if (!hongZhongTiBaoHu)
				return false;
		}

		if (IsHu || hongZhongTiBaoHu) {
			MJ_Action action = new MJ_Action();
			action.m_Action = Constants.ACTION_HU;

			action.bySeatID = bySeatID;
			action.m_cHu.byMj = byActivePai;
			m_history.add(action);

			int byHuSeatID = Constants.INVALID_SEAT_VALUE;
			int bySeat1 = MajHelper.GetNextUser(byLastOutUser);
			int bySeat2 = MajHelper.GetNextUser(bySeat1);
			int bySeat3 = MajHelper.GetNextUser(bySeat2);

			if (bySeatID == bySeat1 || (bySeatID == bySeat2 && GetActionRight(bySeat1) < Constants.ACTION_HU)
					|| (bySeatID == bySeat3 && GetActionRight(bySeat1) < Constants.ACTION_HU
							&& GetActionRight(bySeat2) < Constants.ACTION_HU)) {

				for (int j = 0; j < 4; j++) {
					if (GetActionRight(j) < Constants.ACTION_HU) {
						CleanTempRight(j);
					}
				}
				CleanTempAction();

				CleanTempRight(bySeatID);
				byHuSeatID = bySeatID;
			} else {
				// 无胡操作权限以上的操作
				int userCount = 0; // 操作者数
				for (int i = 0; i < 4; i++) {
					// 跳过自已,和出牌者
					if (i == bySeatID || i == byLastOutUser)
						continue;

					if (GetActionRight(i) == Constants.ACTION_HU) {

						m_tempAction[bySeatID].m_ActionRight = Constants.ACTION_HU;
						m_tempAction[bySeatID].m_cHu = hu;
						break;
					}
					// 胡牌处理

					userCount++;
					CleanTempRight(i);
					if (userCount == 2) {
						CleanTempRight(bySeatID);
						CleanTempAction();
						byHuSeatID = bySeatID;
					}
				}
				if (GetActionRight(bySeatID) == Constants.ACTION_HU) {
					CleanTempRight(bySeatID);
					byHuSeatID = bySeatID;
				}
			}
			CleanTempAction();

			int tmpHandMj[] = new int[Constants.HAND_MJ_MAX];
			Constants.memcpy(tmpHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);

			tmpHandMj[Constants.HAND_MJ_MAX - 1] = byActivePai;

			MajHelper.HuToHandMj(tmpHandMj, l_MajSide.hu);

			// 获取赢家的杠牌信息
			List<BLOCK_GANGINFO> gangList = gangInfosOf(bySeatID);
			// 获取赢家的碰牌的信息
			List<BLOCK_PONGINFO> pengList = pongInfosOf(bySeatID);

			/**
			 * 开牌
			 */
			int iFanTotal = 1;
			m_vecHuType[bySeatID] += "底分+1 ";
			Boolean hasBao = false;
			Boolean hasFeng = false;
			for (int i = 0; i < l_MajSide.Maj.length; i++) {
				if (l_MajSide.Maj[i] == m_caiShen) {
					hasBao = true;
				}
				if (l_MajSide.Maj[i] > 30) {
					hasFeng = true;
				}
			}
			if (!hasBao && hasFeng && m_bIsGang[bySeatID]) {
				if (countKehu > 2) {
					iFanTotal += 2;
					m_vecHuType[bySeatID] += "散铺子杠开+2 ";
				} else {
					iFanTotal += 3;
					m_vecHuType[bySeatID] += "散铺子杠开+3 ";
				}
			}
			/**
			 * 判断宝归位
			 */
			int baoGuiWeiFen = 1;
			ArrayList<HU> baoGuiWeiList = new ArrayList<HU>(list);
			int prevHuIndex = MajTable.hu_Index;
			/**
			 * 其他胡法
			 */
			BLOCK[] blocks = null;
			HU huBlocks = null;
			if (MajTable.hu_Type == 2 && list != null && list.size() != 0) {
				huBlocks = list.get(MajTable.hu_Index);
				// huBlocks = list.get(4);
				blocks = huBlocks.block;
			}

			//小宝 小宝追踪
			int outBao = 0;
			for(int i=0;i<4;i++){
				if(outMjs[bySeatID][i] != 0){
					outBao ++;
				}
			}
			if(m_xiaoBao){
				if(outBao == 1){
					iFanTotal += 2;
					m_vecHuType[bySeatID] += "小宝+2 ";
				}
				if(outBao > 1){
					iFanTotal += 4;
					m_vecHuType[bySeatID] += "小宝追踪+4 ";
				}
			}

			/**
			 * 四宝分
			 */
			int countCaiShen = Constants.countof(l_MajSide.Maj, m_caiShen);
			if (countCaiShen == 4) {
				iFanTotal += 20;
				m_vecHuType[bySeatID] += "四宝+20 ";
			}
			
			/**
			 * 十三烂胡牌
			 */
			int shisanlan = MajHelper.IsShiSanLan(l_MajSide.Maj, byActivePai, l_MajSide.hu, m_caiShen, bZiMo, list);

			/**
			 * 七对子
			 */
			int retType = TDHHelper.IsPaiXinQiDuiZi(l_MajSide.Maj, l_MajSide.hu, byActivePai, m_caiShen, bZiMo);

			/**
			 * 清一色
			 */
			Boolean qingyise = false;
			Boolean hasGang = false;
			if (MajHelper.IsQingYiSe(l_MajSide.Maj, byActivePai, huBlocks, m_caiShen, bZiMo, list, gangList,
					pengList)) {
				qingyise = true;
			}
			if (gangList.size() > 0 && gangList.get(0).first != 0) {
				hasGang = true;
			}
			// 混一色
			Boolean fengyise = MajHelper.IsPaiXinFengYiSe(l_MajSide.Maj, m_caiShen, gangList, pengList);

			Boolean duiduihu = false;
			if (shisanlan == 0 && retType == 0 && countCaiShen != 4) {
				duiduihu = MajHelper.IsPaiXinDuiDuiHu(l_MajSide.Maj, huBlocks, gangList, pengList);
			}

			if (!hasBao && hasFeng && !fengyise && !duiduihu && !m_bIsGang[bySeatID]) {
				if(countKehu == 2){
					iFanTotal += 1;
					m_vecHuType[bySeatID] += "散铺子+1 ";
				}
			}
			if(hasBao && hasFeng &&!fengyise && !duiduihu && !m_bIsGang[bySeatID] && countKehu == 34){
				iFanTotal += 1;
				m_vecHuType[bySeatID] += "散铺子+1 ";
			}
			if (duiduihu && qingyise) {
				if (countKehu == 2) {
					iFanTotal += 16;
					m_vecHuType[bySeatID] += "清一色对对胡+16 ";
				} else {
					iFanTotal += 8;
					m_vecHuType[bySeatID] += "清一色对对胡+8 ";
				}
			}

			if (duiduihu && hasGang) {
				if (countKehu == 2) {
					iFanTotal += 8;
					m_vecHuType[bySeatID] += "对对胡杠牌+8 ";
				} else {
					iFanTotal += 6;
					m_vecHuType[bySeatID] += "对对胡杠牌+6 ";
				}
			}
			if (duiduihu && !hasGang) {
				if (countKehu == 2) {
					iFanTotal += 6;
					m_vecHuType[bySeatID] += "对对胡+6 ";
				} else {
					iFanTotal += 4;
					m_vecHuType[bySeatID] += "对对胡+4 ";
				}
			}

			Boolean kuangkuang = false;
			Boolean qifengquan = false;
			Boolean dageda = false;
			if (shisanlan == 10) {
				kuangkuang = MajHelper.IsKuangKuang(l_MajSide.Maj, m_caiShen);// 狂狂
				qifengquan = MajHelper.IsQfq(l_MajSide.Maj, m_caiShen);// 七风全
				dageda = MajHelper.IsDageda(l_MajSide.Maj, m_caiShen);//大哥大
			}
			if (kuangkuang) {
				if(countKehu == 2){
					iFanTotal += 12;
					m_vecHuType[bySeatID] += "十三散狂狂+12 ";
				}else{
					iFanTotal += 6;
					m_vecHuType[bySeatID] += "十三散狂狂+6 ";
				}
			}
			if (shisanlan == 10 && !kuangkuang && !dageda) {
				if(countKehu == 2){
					iFanTotal += 6;
					m_vecHuType[bySeatID] += "十三散+6 ";
				}else{
					iFanTotal += 3;
					m_vecHuType[bySeatID] += "十三散+3 ";
				}
			}
			if (qifengquan) {
				iFanTotal += 1;
				m_vecHuType[bySeatID] += "七风全+1 ";
			}
			if(dageda && !kuangkuang){
				if(countKehu == 2){
					iFanTotal += 8;
					m_vecHuType[bySeatID] += "十三散大哥大+8 ";
				}
				if(countKehu > 2){
					iFanTotal += 4;
					m_vecHuType[bySeatID] += "十三散大哥大+4 ";
				}
			}

			if (retType == Constants.QI_DUI_ZI) {
				if (countKehu == 2) {
					if (qingyise) {
						iFanTotal += 10;
						m_vecHuType[bySeatID] += "清一色七小对+10 ";
					} else if (fengyise && m_fengYiSe) {
						iFanTotal += 10;
						m_vecHuType[bySeatID] += "风一色七小对+10 ";
					} else {
						iFanTotal += 4;
						m_vecHuType[bySeatID] += "七小对+4 ";
					}
				} else {
					if (qingyise) {
						iFanTotal += 5;
						m_vecHuType[bySeatID] += "清一色七小对+5 ";
					} else if (fengyise && m_fengYiSe) {
						iFanTotal += 5;
						m_vecHuType[bySeatID] += "风一色七小对+5 ";
					} else {
						if(countCaiShen != 4){
							iFanTotal += 2;
							m_vecHuType[bySeatID] += "七小对+2 ";
						}
					}
				}
			}
			if (retType == 1) {
				if (countKehu == 2) {
					if (qingyise) {
						iFanTotal += 12;
						m_vecHuType[bySeatID] += "清一色豪华七小对+12 ";
					} else if (fengyise && m_fengYiSe) {
						iFanTotal += 12;
						m_vecHuType[bySeatID] += "风一色豪华七小对+12 ";
					} else {
						iFanTotal += 5;
						m_vecHuType[bySeatID] += "豪华七小对+5 ";
					}
				} else {
					if (qingyise) {
						iFanTotal += 6;
						m_vecHuType[bySeatID] += "清一色豪华七小对+6 ";
					} else if (fengyise && m_fengYiSe) {
						iFanTotal += 6;
						m_vecHuType[bySeatID] += "风一色豪华七小对+6 ";
					} else {
						iFanTotal += 3;
						m_vecHuType[bySeatID] += "豪华七小对+3 ";
					}
				}
			}
			if (retType == 2) {
				if (countKehu == 2) {
					if (qingyise) {
						iFanTotal += 14;
						m_vecHuType[bySeatID] += "清一色超豪华七小对+14 ";
					} else if (fengyise && m_fengYiSe) {
						iFanTotal += 14;
						m_vecHuType[bySeatID] += "风一色超豪华七小对+14 ";
					} else {
						iFanTotal += 6;
						m_vecHuType[bySeatID] += "超豪华七小对+6 ";
					}
				} else {
					if (qingyise) {
						iFanTotal += 7;
						m_vecHuType[bySeatID] += "清一色超豪华七小对+7 ";
					} else if (fengyise && m_fengYiSe) {
						iFanTotal += 7;
						m_vecHuType[bySeatID] += "风一色超豪华七小对+7 ";
					} else {
						iFanTotal += 4;
						m_vecHuType[bySeatID] += "超豪华七小对+4 ";
					}
				}
			}
			if (retType == 3) {
				if (countKehu == 2) {
					if (qingyise) {
						iFanTotal += 16;
						m_vecHuType[bySeatID] += "清一色三豪华七小对+16 ";
					} else if (fengyise && m_fengYiSe) {
						iFanTotal += 16;
						m_vecHuType[bySeatID] += "风一色三豪华七小对+16 ";
					} else {
						iFanTotal += 10;
						m_vecHuType[bySeatID] += "三豪华七小对+7 ";
					}
				} else {
					if (qingyise) {
						iFanTotal += 8;
						m_vecHuType[bySeatID] += "清一色三豪华七小对+8 ";
					} else if (fengyise && m_fengYiSe) {
						iFanTotal += 8;
						m_vecHuType[bySeatID] += "风一色三豪华七小对+8 ";
					} else {
						iFanTotal += 5;
						m_vecHuType[bySeatID] += "三豪华七小对+5 ";
					}
				}
			}

			if (m_fengYiSe && fengyise && retType == 0) {
				if (countKehu == 2) {
					iFanTotal += 8;
					m_vecHuType[bySeatID] += "风一色+8 ";
				} else {
					iFanTotal += 4;
					m_vecHuType[bySeatID] += "风一色+4 ";
				}
			}

			if (qingyise && retType == 0 && !hasGang) {
				if (countKehu == 2) {
					iFanTotal += 8;
					m_vecHuType[bySeatID] += "清一色铺子+8 ";
				} else {
					iFanTotal += 4;
					m_vecHuType[bySeatID] += "清一色铺子+4 ";
				}
			}
			if (qingyise && hasGang) {
				if (countKehu == 2) {
					iFanTotal += 10;
					m_vecHuType[bySeatID] += "清一色杠牌+10 ";
				} else {
					iFanTotal += 5;
					m_vecHuType[bySeatID] += "清一色杠牌+5 ";
				}
			}

			if (m_tiandiHu && m_bTianHu) {
				iFanTotal += 30;
				m_vecHuType[bySeatID] += "天胡+30  ";
			}
			if (m_tiandiHu && bySeatID != m_byZhuang && m_bDiHu[bySeatID] == true) {
				iFanTotal += 30;
				m_vecHuType[bySeatID] += "地胡+30  ";
			}
			int byHuType[] = new int[50];
			Constants.memset(byHuType, 0, byHuType.length);
			iFanTotal += AdjustHu(byHuType);
			lastZhuang = m_byZhuang;

			if (bySeatID == byLastOutUser) {// 自摸 都扣2x

				for (int k = 0; k < 4; k++) {
					if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
						// 负值，代表输的分数
						roundScore[k] -= iFanTotal;
					}
				}
				for (int k = 0; k < 4; k++) {
					if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
						// 正值，代表赢的分数
						roundScore[bySeatID] += 0 - roundScore[k];
					}
				}
			}
			for (int k = 0; k < 4; k++) {
				m_vecRoundScore[k] = roundScore[k];
				m_vecResultScore[k] += roundScore[k];
			}
			for (int k = 0; k < 4; k++) {
				// 正在进行游戏中用户的信息
				m_pIUserItem[k].lUserScore += roundScore[k];

				if (roundScore[k] > 0) {
					m_vecWinScore[k] += roundScore[k];
				} else {
					m_vecLoseScore[k] += roundScore[k];
				}
			}
			m_vecZiMo[bySeatID] = bZiMo ? 1 : 0;
			m_kReport[bySeatID].cntHu++;
			if (bZiMo) {
				m_kReport[bySeatID].cntZiMo++;
			}
			{
				SUBCMD_S_HU cmd = new SUBCMD_S_HU();

				cmd.byWinner = bySeatID;
				if (bySeatID == byLastOutUser) {
					cmd.byFangQiang = Constants.INVALID_CHAIR;
				}
				cmd.byHuMj = byActivePai;
				for (int k = 0; k < 4; k++) {
					cmd.winScore[k] = roundScore[k];
					cmd.resultScore[k] = m_pIUserItem[k].lUserScore;
				}
				SendData(Constants.INVALID_CHAIR, cmd.getJsonData());
			}

			m_wDealErrorDelay = 0;

			m_bIsHu[bySeatID] = true;

			int cntHuRight = 0; // 操作者数
			for (int i = 0; i < 4; i++) {
				// 跳过自已,和出牌者
				if (i == bySeatID || i == byLastOutUser)
					continue;

				if (GetActionRight(i) == Constants.ACTION_HU) {

					cntHuRight++;
					break;
				}
			}

			l_MajSide.SetMoPai(byActivePai);
			if (cntHuRight == 0) {
				CleanTempAction();

				OnEventGameEnd(bySeatID, Constants.GAME_END_NORMAL);
			}

			m_byZhuang = bySeatID;
			for (int i = 0; i < 4; i++) {
				m_bIsGang[i] = false;
			}

		}
		return true;
	}

	int GetZhongMa(int bySeatID, int vecMaPai[], int vecZhongMa[], int cntMaPai) {
		return 0;
	}

	// 用户吃牌
	boolean OnUserChi(int bySeatID, SUBCMD_C_Chi Chi) {
		if (bySeatID >= 4 || Chi == null) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);

		if ((l_MajSide.GetHandMjCount() % 3) != 1) {
			return false;
		}
		if (m_qiuPaiNum[bySeatID][m_MajLogic.GetCurrentUser()] >= 2) {
			return false;// 不能三吃
		}
		m_MajLogic.SetCurrentAction(0);
		// 设置变量
		// SUBCMD_C_Chi Chi = ( SUBCMD_C_Chi * )pDataBuffer;
		if (GetActionRight(bySeatID) < Constants.ACTION_CHI) {
			return false;
		}
		for (int i = 0; i < 4; i++) {
			m_bDiHu[i] = false;
		}
		int byLastOutMj = m_MajLogic.GetLastOutMj();

		MJ_Action action = new MJ_Action();
		action.m_Action = Constants.ACTION_CHI;

		action.bySeatID = bySeatID;
		action.m_cChi.byMj = byLastOutMj;
		action.m_cChi.nChiType = Chi.nChiType;
		m_history.add(action);

		// 无碰操作权限以上的操作
		int userCount = 0; // 操作者数
		for (int i = 0; i < 4; i++) {
			// 跳过自已,和出牌者
			if (i == bySeatID || i == m_MajLogic.GetCurrentUser())
				continue;

			if (GetActionRight(i) > Constants.ACTION_CHI) {
				m_tempAction[bySeatID].m_ActionRight = Constants.ACTION_CHI;
				m_tempAction[bySeatID].m_cChi = Chi;
				CleanTempRight(bySeatID);
				m_byRight[bySeatID][0] = 1;
				break;
			} // 吃处理
			else {
				userCount++;
				CleanTempRight(i);
				if (userCount == 2) {
					CleanTempRight(bySeatID);
					// 处理吃

					MJ_BLOCK block;
					block = (MJ_BLOCK) MajHelper.Chi(l_MajSide.Maj, m_MajLogic.GetLastOutMj(), Chi.nChiType, m_caiShen);
					MajHelper.AddBlock(l_MajSide.hu, block);
					l_MajSide.SortCard();

					// 发送消息
					SUBCMD_S_Chi cmd = new SUBCMD_S_Chi();
					Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
					cmd.block = block;
					cmd.byActionUser = bySeatID;
					cmd.nChiType = Chi.nChiType;
					cmd.byMj = byLastOutMj;
					// 上次操作玩家-出牌者
					cmd.byOutMjUser = m_MajLogic.GetCurrentUser();
					m_MajLogic.GetMajSide(m_MajLogic.GetCurrentUser()).BeiChiPai();
					m_qiuPaiNum[bySeatID][m_MajLogic.GetCurrentUser()]++;// 吃碰牌数量
					// 当前用户变换
					m_MajLogic.SetCurrentUser(bySeatID);

					for (int j = 0; j < 4; j++) {
						Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
						if (j == bySeatID) {
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						} else {
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
								if (cmd.byHandMj[k] != Constants.INVALID_CARD) {
									cmd.byHandMj[k] = 0;
								}
							}
						}
						String sData = cmd.getJsonData();
						SendData(m_pIUserItem[j].dwUserID, sData);
						m_wDealErrorDelay = 0;
					}
					CleanTempAction();
				}
			}
		}
		SendYuPai();
		return true;
	}

	// 用户杠牌
	boolean OnUserGang(int bySeatID, SUBCMD_C_Gang Gang) {
		/* printf("GANG[%d]\n",bySeatID); */
		if (bySeatID >= 4 || Gang == null) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		// SUBCMD_C_Gang Gang = ( SUBCMD_C_Gang * )pDataBuffer;
		// 权限效验
		if (GetActionRight(bySeatID) < Constants.ACTION_GANG) {
			return false;
		}
		if (m_qiuPaiNum[bySeatID][m_MajLogic.GetCurrentUser()] >= 2) {
			return false;// 不能三吃
		}
		// 获取当前出牌的人
		int byLastOutUser = m_MajLogic.GetCurrentUser();
		MJ_Action action = new MJ_Action();
		action.m_Action = Constants.ACTION_CHI;

		action.bySeatID = bySeatID;
		action.m_cGang.byMj = Gang.byGangMj;
		action.m_cGang.nGangMode = Gang.nGangMode;
		m_history.add(action);

		/*
		 * 获取杠牌的信息
		 */
		BLOCK_GANGINFO gangInfo = new BLOCK_GANGINFO();
		gangInfo.reset();
		gangInfo.GangUser = bySeatID;
		gangInfo.first = Gang.byGangMj;
		gangInfo.style = Gang.nGangMode;
		gangInfo.dianGangUser = (Gang.nGangMode == 1) ? byLastOutUser : bySeatID;
		gangInfosOf(gangInfo.GangUser).add(gangInfo);

		// 无杠操作权限以上的操作
		int userCount = 0; // 操作者数
		for (int i = 0; i < 4; i++) {
			// 跳过自已,和出牌者
			// 遍历的时候不处理自己跟出牌的那个人
			if (i == bySeatID || i == byLastOutUser)
				continue;

			if (GetActionRight(i) > Constants.ACTION_GANG) {
				m_tempAction[bySeatID].m_ActionRight = Constants.ACTION_GANG;
				m_tempAction[bySeatID].m_cGang = Gang;
				CleanTempRight(bySeatID);
				m_byRight[bySeatID][2] = 1;
				break;
			}

			// 杠处理
			else {
				userCount++;
				CleanTempRight(i);
				if (userCount == 2) {
					switch (Gang.nGangMode) {
					case 1: // 普通杠
					{
						CleanTempRight(bySeatID);
						MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
						MJ_BLOCK block;
						block = (MJ_BLOCK) MajHelper.MGang(l_MajSide.Maj, m_MajLogic.GetLastOutMj());

						MajHelper.AddBlock(l_MajSide.hu, block);
						block.origValue = MajHelper.GetRelativeSeat(bySeatID, byLastOutUser);
						m_byMingGang[bySeatID] += 1;

						int k1 = MajHelper.GetNextUser(bySeatID);
						int k2 = MajHelper.GetNextUser(k1);
						int k3 = MajHelper.GetNextUser(k2);

						m_vecGangScore[bySeatID] += 1 * 3;
						m_vecGangScore[k1] -= 1;
						m_vecGangScore[k2] -= 1;
						m_vecGangScore[k3] -= 1;
						// m_vecGangScore[bySeatID] += 3;
						// m_vecGangScore[byLastOutUser] -= 3;
						m_kReport[bySeatID].cntGang++;
						m_kReport[byLastOutUser].cntDianGang++;

						m_MajLogic.SetCurrentAction(Constants.ACTION_GANG);
						// 发送杠牌消息
						SUBCMD_S_Gang cmd = new SUBCMD_S_Gang();

						cmd.byActionUser = bySeatID;
						cmd.byOutMjUser = m_MajLogic.GetCurrentUser();
						cmd.byMj = block.first;
						cmd.block = block;
						cmd.gangType = 1;
						cmd.byBuMj = 255;

						cmd.bZiMoGang = 0;
						Constants.memset(cmd.bHu, 0, Constants.sizeof(cmd.bHu));

						CleanTempAction();

						m_MajLogic.GetMajSide(m_MajLogic.GetCurrentUser()).BeiChiPai();
						m_qiuPaiNum[bySeatID][m_MajLogic.GetCurrentUser()]++;// 吃碰牌数量
						// 当前用户变换
						m_MajLogic.SetCurrentUser(bySeatID);

						for (int j = 0; j < 4; j++) {
							Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
							if (j == bySeatID) {
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							} else {
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
								for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
									if (cmd.byHandMj[k] != Constants.INVALID_CARD) {
										cmd.byHandMj[k] = 0;
									}
								}

							}
							String sData = cmd.getJsonData();
							SendData(m_pIUserItem[j].dwUserID, sData);
							m_wDealErrorDelay = 0;
						}

						// 杠牌者摸牌
						OnUserTouchMj(bySeatID, Constants.ACTION_GANG_BUPAI);
					}
						break;
					case 2: // 补杠
					{
						CleanTempRight(bySeatID);
						MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
						MajHelper.ZMGang(l_MajSide.Maj, l_MajSide.hu, Gang.byGangMj);
						m_MajLogic.GetMajSide(bySeatID).SortCard(Constants.HAND_MJ_MAX);

						m_byBuGang[bySeatID] += 1;
						int k1 = MajHelper.GetNextUser(bySeatID);
						int k2 = MajHelper.GetNextUser(k1);
						int k3 = MajHelper.GetNextUser(k2);

						m_vecGangScore[bySeatID] += 1 * 3;
						m_vecGangScore[k1] -= 1;
						m_vecGangScore[k2] -= 1;
						m_vecGangScore[k3] -= 1;
						m_kReport[bySeatID].cntGang++;

						m_MajLogic.SetCurrentAction(Constants.ACTION_GANG);
						MJ_BLOCK block = new MJ_BLOCK();
						block.style = Constants.BLOCK_GANG;
						block.first = Gang.byGangMj;
						// 发送杠牌消息
						SUBCMD_S_Gang cmd = new SUBCMD_S_Gang();
						cmd.byActionUser = bySeatID;
						cmd.byOutMjUser = m_MajLogic.GetCurrentUser();
						cmd.block = block;
						cmd.gangType = 2;
						cmd.byMj = Gang.byGangMj;
						cmd.byBuMj = 255;
						cmd.bTing = 0;
						Constants.memset(cmd.bHu, 0, Constants.sizeof(cmd.bHu));

						m_MajLogic.SetCurrentUser(bySeatID);
						for (int j = 0; j < 4; j++) {

							/**
							 * 处理抢杠胡
							 */
							int byIndex = bySeatID + j + 1;
							byIndex = byIndex % 4;
							Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
							if (byIndex == bySeatID) {
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							} else {
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
								for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
									if (cmd.byHandMj[k] != Constants.INVALID_CARD) {
										cmd.byHandMj[k] = 0;
									}
								}

								if (byIndex == MajHelper.GetNextUser(bySeatID)) {
									MajSide l_TmpMajSide = m_MajLogic.GetMajSide(byIndex);
									m_MajLogic.SetLastOutMj(Gang.byGangMj);

//									ArrayList<HU> list = new ArrayList<HU>();
//
//									m_byRight[byIndex][4] = MajHelper.HongZongTibaoHu(l_TmpMajSide.Maj, Gang.byGangMj,
//											l_TmpMajSide.hu, m_caiShen, false, list,m_siBao) ? 1 : 0;

									// m_bQiangGangHu[byIndex] =
									// m_byRight[byIndex][4] == 0 ? false :
									// true;
//									m_bQiangGangHu[byIndex] = false;
//									cmd.bHu[byIndex] = m_byRight[byIndex][4];
									// 手中有宝牌不能抢杠胡
//									if (Constants.countof(l_TmpMajSide.Maj, m_caiShen) > 0) {
//										m_bQiangGangHu[byIndex] = false;
//										m_byRight[byIndex][4] = 0;
//										cmd.bHu[byIndex] = 0;
//									}
//
//									if (cmd.bHu[byIndex] != 0) {
//										this.m_roundHuSeated[this.m_roundHuCount] = byIndex;
//										this.m_roundHuCount++;
//									}
								} else if (byIndex != bySeatID) {
									MajSide l_TmpMajSide = m_MajLogic.GetMajSide(byIndex);
									m_MajLogic.SetLastOutMj(Gang.byGangMj);
									ArrayList<HU> list = new ArrayList<HU>();
									m_byRight[byIndex][4] = MajHelper.HongZongTibaoHu(l_TmpMajSide.Maj, Gang.byGangMj,
											l_TmpMajSide.hu, m_caiShen, false, list,m_siBao) ? 1 : 0;

									// m_bQiangGangHu[byIndex] =
									// m_byRight[byIndex][4] == 0 ? false :
									// true;
									m_bQiangGangHu[byIndex] = false;
									// cmd.bHu[byIndex] = m_byRight[byIndex][4];
									// 手中有宝牌不能抢杠胡
									if (Constants.countof(l_TmpMajSide.Maj, m_caiShen) > 0) {
										m_bQiangGangHu[byIndex] = false;
										m_byRight[byIndex][4] = 0;
										cmd.bHu[byIndex] = 0;
									}
									cmd.bHu[byIndex] = 0;
									if (cmd.bHu[byIndex] != 0) {
										this.m_roundHuSeated[this.m_roundHuCount] = byIndex;
										this.m_roundHuCount++;

									}
								}
							}

							String sData = cmd.getJsonData();
							SendData(m_pIUserItem[byIndex].dwUserID, sData);
							m_wDealErrorDelay = 0;
						}
						CleanTempAction();

						if (HasQiangGangHuRight() == false) {
							// 当前用户变换
							// 杠牌者摸牌
							OnUserTouchMj(bySeatID, Constants.ACTION_GANG_BUPAI);
						}
					}
						break;
					case 4: // 暗杠
					{
						CleanTempRight(bySeatID);
						MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
						MJ_BLOCK block;
						block = (MJ_BLOCK) MajHelper.AnGang(l_MajSide.Maj, Gang.byGangMj);
						MajHelper.AddBlock(l_MajSide.hu, block);
						m_MajLogic.GetMajSide(bySeatID).SortCard(Constants.HAND_MJ_MAX);

						m_byAnGang[bySeatID] += 1;
						int k1 = MajHelper.GetNextUser(bySeatID);
						int k2 = MajHelper.GetNextUser(k1);
						int k3 = MajHelper.GetNextUser(k2);

						m_vecGangScore[bySeatID] += 1 * 3;
						m_vecGangScore[k1] -= 1;
						m_vecGangScore[k2] -= 1;
						m_vecGangScore[k3] -= 1;
						m_kReport[bySeatID].cntAnGang++;
						m_kReport[bySeatID].cntGang++;

						m_MajLogic.SetCurrentAction(Constants.ACTION_GANG);
						// 消息处理
						SUBCMD_S_Gang cmd = new SUBCMD_S_Gang();
						cmd.block = block;
						cmd.byActionUser = bySeatID;
						cmd.gangType = 4;
						cmd.byMj = block.first;
						cmd.byBuMj = 255;
						cmd.bZiMoGang = 0;
						cmd.bTing = 0;
						Constants.memset(cmd.bHu, 0, Constants.sizeof(cmd.bHu));
						for (int j = 0; j < 4; j++) {
							Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
							if (j == bySeatID) {
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							} else {
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
								for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
									if (cmd.byHandMj[k] != Constants.INVALID_CARD) {
										cmd.byHandMj[k] = 0;
									}
								}
							}

							String sData = cmd.getJsonData();
							SendData(m_pIUserItem[j].dwUserID, sData);
							m_wDealErrorDelay = 0;
						}
						CleanTempAction();
						// 发送消息

						// 杠牌者摸牌
						OnUserTouchMj(bySeatID, Constants.ACTION_GANG_BUPAI);

					}
						break;
					}
				}
			}
		}
		{
			MajSide l_MajSide0 = m_MajLogic.GetMajSide(0);
			System.out.println("OnUserGang 2:" + 0 + ":" + IJsonExport.sprintf_INT32(l_MajSide0.Maj, 14));
		}

		SendYuPai();
		return true;
	}

	boolean OnUserTing(int bySeatID) {
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		if (m_byChuPaiCount[bySeatID] == 0) {
			m_bDiTing[bySeatID] = true;
		}
		m_MajLogic.SetCurrentAction(Constants.ACTION_TING);
		SUBCMD_S_Ting cmd = new SUBCMD_S_Ting();
		cmd.byActionUser = bySeatID;

		m_bTing[bySeatID] = true;

		String sData = cmd.getJsonData();
		SendData(m_pIUserItem[bySeatID].dwUserID, sData);
		m_wDealErrorDelay = 0;
		return false;
	}

	int AdjustHu(int byHuType[]) {
		int total = 0;
		for (int i = 0; i < byHuType.length; i++) {
			total += byHuType[i];
		}
		return total;
	}

	String HuToString(int byHuType[]) {
		String strHuType = "";
		for (int i = 0; i < byHuType.length; i++) {
			if (byHuType[i] != 0) {
				switch (i) {

				case Constants.QI_DUI_ZI:// 七对子 1番 2分
					strHuType += "七对子 x2  ";
					break;

				}
			}
		}
		return strHuType;
	}

	void OnEventGameStart() {
		Init(Constants.INIT_NEWROUND);

		FaPai();
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				m_pIUserItem[i].cbUserStatus = Constants.US_PLAY;
			}
		}
		for (int i = 0; i < 9; i++) {
			m_vecMaPai[i] = 0;
		}
		m_bTableStarted = true;
		m_bGameStarted = true;
	}

	void OnEventGameEnd(int bySeatID, int cbReason) {

		m_bGameStarted = false;
		int cntUser = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 0) {
				cntUser++;
			}
		}
		if (cbReason != Constants.GAME_END_DISMISS) {

			m_wJieSuanRound++;

			SUBCMD_S_JIESUAN cmd = new SUBCMD_S_JIESUAN();
			cmd.byRound = m_byRound;
			cmd.byZhuang = m_byZhuang;
			cmd.byLianZhuang = m_byLianZhuang;
			cmd.vecMaPai = m_vecMaPai;

			for (int i = 0; i < 4; i++) {

				cmd.userJieSuan[i].lRoundScore = m_vecRoundScore[i];
				cmd.userJieSuan[i].strHuType = m_vecHuType[i];

				MajSide l_MajSide = m_MajLogic.GetMajSide(i);

				Constants.memcpy(cmd.userJieSuan[i].byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
				if (m_bIsHu[i] && cmd.userJieSuan[i].byHandMj[Constants.HAND_MJ_MAX - 1] == Constants.INVALID_CARD) {
					cmd.userJieSuan[i].byHandMj[Constants.HAND_MJ_MAX - 1] = m_MajLogic.GetLastOutMj();
				}
				Constants.memcpy(cmd.userJieSuan[i].hu, l_MajSide.hu, Constants.sizeof(cmd.userJieSuan[i].hu));
			}
			SendData(cmd.getJsonData());

		}
		for (int i = 0; i < 4; i++) {
			m_kReport[i].lUid = m_pIUserItem[i].dwUserID;

			m_kReport[i].lResultScore = m_vecResultScore[i];

		}
		if (m_byRound <= 1 && cbReason == GAME_END_DISMISS && m_wJieSuanRound < 1) {
			SUBCMD_S_DismissRoom cmd = new SUBCMD_S_DismissRoom();
			cmd.lUid = 0L;
			cmd.cbResult = 0;
			cmd.m_wUserChairID = 0;
			cmd.m_dwTableID = m_dwTableID;

			SendData(cmd.getJsonData());
			DelayRemove();

			QpGameMgr.getInstance().OnDismissRoom(this);

		} else if (m_byRound == m_byMaxRound || cbReason == GAME_END_DISMISS) {
			int before_cost[] = new int[5];
			int after_cost[] = new int[5];

			int cost[] = new int[5];
			for (int i = 0; i < 5; i++) {
				before_cost[i] = 0;
				cost[i] = 0;
				after_cost[i] = 0;
			}
			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[i].dwUserID);
					if (user != null) {
						before_cost[i] = user.getGem(0);
					}
				}
			}
			int minRound = 1;
			if (m_byMaxRound > 8) {
				minRound = 4;
			}

			if (m_byRound >= minRound) {
				if (m_payWay.equalsIgnoreCase("WINPAY")) {
					List<Integer> winuser = new ArrayList<Integer>();
					if (m_vecRoundScore[0] == m_vecRoundScore[1] && m_vecRoundScore[0] == m_vecRoundScore[2]
							&& m_vecRoundScore[0] == m_vecRoundScore[3]) {
						winuser.add(0);
						winuser.add(1);
						winuser.add(2);
						winuser.add(3);
					} else {
						int max = -1;
						for (int i = 0; i < 4; i++) {
							if (m_vecRoundScore[i] > max) {
								max = m_vecRoundScore[i];
							}
						}
						for (int i = 0; i < 4; i++) {
							if (m_vecRoundScore[i] == max) {
								winuser.add(i);
							}
						}
					}
					float rate = m_byRound * 1.0f / m_byMaxRound;
					rate *= m_maxCostGem;
					Float frate = new Float(rate);
					int cost_gem = frate.intValue();
					cost_gem /= winuser.size();

					for (int i = 0; i < 5; i++) {
						if (m_pIUserItem[i].dwUserID > 0 && winuser.indexOf(i) != -1) {
							SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[i].dwUserID);
							if (user != null && cost_gem < 20) {
								user.getGem(0 - cost_gem);
								cost[i] = 0 - cost_gem;
							}
						}
					}
				}
				if (m_payWay == "FZPAY") {
					float rate = m_byRound * 1.0f / m_byMaxRound;
					rate *= m_maxCostGem;
					Float frate = new Float(rate);
					int cost_gem = frate.intValue();

					if (m_Creator > 0) {
						SHMUser user = dthall.getInstance().getUserInfo(m_Creator);
						if (user != null && cost_gem < 200) {
							user.getGem(0 - cost_gem);
						}
					} else {
						SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[0].dwUserID);
						if (user != null && cost_gem < 200) {
							user.getGem(0 - cost_gem);
						}
						cost[0] = 0 - cost_gem;
					}
				}
				if (m_payWay == "AAPAY") {
					float rate = m_byRound * 1.0f / m_byMaxRound;
					rate *= m_maxCostGem;
					Float frate = new Float(rate);
					int cost_gem = frate.intValue();
					for (int i = 0; i < 5; i++) {
						if (m_pIUserItem[i].dwUserID > 0) {
							SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[i].dwUserID);
							if (user != null && cost_gem < 40) {
								user.getGem(0 - cost_gem);
								cost[i] = 0 - cost_gem;
							}
						}
					}
				}

				if(m_payWay == "CLUBPAY"){
					float rate = m_byRound * 1.0f / m_byMaxRound;
					rate *= m_maxCostGem;
					Float frate = new Float(rate);
					int cost_gem = frate.intValue();
					DbInfoMgr.getInstance().costClubOwnerGem(this.m_clubOwnerId,cost_gem);
				}
				for (int i = 0; i < 5; i++) {
					if (m_pIUserItem[i].dwUserID > 0) {
						SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[i].dwUserID);
						if (user != null) {
							after_cost[i] = user.getGem(0);
						}
					}
				}
			}

			SUBCMD_S_REPORT cmd = new SUBCMD_S_REPORT();
			cmd.cbReason = cbReason;
			cmd.cbType = 0;
			// Constants.memcpy(cmd.userReport, m_kReport,
			// Constants.sizeof(m_kReport));
			for (int i = 0; i < 4; i++) {
				cmd.userReport[i].lUid = m_kReport[i].lUid;
				cmd.userReport[i].cntZiMo = m_kReport[i].cntZiMo;
//				cmd.userReport[i].cntHu = m_kReport[i].cntHu;
//				cmd.userReport[i].cntDianPao = m_kReport[i].cntDianPao;
				cmd.userReport[i].cntGang = m_kReport[i].cntGang;
//				cmd.userReport[i].cntAnGang = m_kReport[i].cntAnGang;
//				cmd.userReport[i].cntDianGang = m_kReport[i].cntDianGang;
				cmd.userReport[i].lWinScore = m_kReport[i].lWinScore;
				cmd.userReport[i].lLoseScore = m_kReport[i].lLoseScore;
				cmd.userReport[i].lResultScore = m_kReport[i].lResultScore;
				m_vecResultScore[i] = m_kReport[i].lResultScore;
			}

			SendData(cmd.getJsonData());

			log_counter++;
			log_counter = log_counter % 100;
			Long t = System.currentTimeMillis() / 1000;
			Long battle_id = (t % 1000000) * 100 + log_counter;

			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String created = df.format(new Date());
			{

				JSONObject root = new JSONObject();

				root.put("command", "save_battle_log");
				root.put("battle_id", battle_id);

				root.put("room_type", GetType());
				root.put("hallwfdesc", m_strParam);

				root.put("room_id", m_dwTableID);
				root.put("creator", GetCreator());

				root.put("jushu", m_byMaxRound);
				root.put("limitscore", 0);

				if (m_payWay == "FZPAY") {
					root.put("payway", 0);
				} else if (m_payWay == "AAPAY") {
					root.put("payway", 1);
				} else {
					root.put("payway", 2);
				}
				root.put("created", created);
				root.put("uid0", m_pIUserItem[0].dwUserID);
				root.put("nickname0", m_pIUserItem[0].szNickName);
				root.put("score0", m_vecResultScore[0]);
				root.put("cost0", cost[0]);
				root.put("uid1", m_pIUserItem[1].dwUserID);
				root.put("nickname1", m_pIUserItem[1].szNickName);
				root.put("score1", m_vecResultScore[1]);
				root.put("cost1", cost[1]);
				root.put("uid2", m_pIUserItem[2].dwUserID);
				root.put("nickname2", m_pIUserItem[2].szNickName);
				root.put("score2", m_vecResultScore[2]);
				root.put("cost2", cost[2]);
				root.put("uid3", m_pIUserItem[3].dwUserID);
				root.put("nickname3", m_pIUserItem[3].szNickName);
				root.put("score3", m_vecResultScore[3]);
				root.put("cost3", cost[3]);
				root.put("uid4", 0);
				root.put("nickname4", "");
				root.put("score4", 0);
				root.put("cost4", 0);
				root.put("battle_video", "");
				if(m_clubId != 0){
					//club
					root.put("clubid", m_clubId);
					root.put("wfdesc", m_wanFaStr);
					if(m_payWay == "CLUBPAY"){
						root.put("payway", 10);
					}
					ClubRedis.getInstance().addClubBattleLog(m_clubId,root.toString());
				}
				try
				{
					for(int i =0;i<5;i++)
					{
						if(m_pIUserItem[i].dwUserID > 0 && cost[i] != 0)
						{
							JSONObject root_cost = new JSONObject();
							root_cost.put("command", "save_charge_log");
							root_cost.put("created", created);
							root_cost.put("uid", (int) m_pIUserItem[i].dwUserID);
							root_cost.put("before_cost", (int) before_cost[i]);
							root_cost.put("after_cost", (int) after_cost[i]);
							root_cost.put("cost", (int) cost[i]);
							root_cost.put("reason", " û " + m_pIUserItem[0].dwUserID + "          ˸ " + m_byMaxRound + "   " + m_payWay );
							root_cost.put("room_id", m_dwTableID);							
							GameDB.getInstance().push_task(null, root_cost);
						}
					}	
				}catch(Exception e)
				{
					e.printStackTrace();
				}
				Replay.save(m_dwTableID, new org.json.JSONObject(root.toString()));
			}

			m_bTableStarted = false;
			for (int i = 0; i < 4; i++) {// 清除牌局数据
				m_vecResultScore[i] = 0;
			}

			DelayRemove();

			QpGameMgr.getInstance().OnDismissRoom(this);
		}
	}

	private long time(Object object) {
		return System.currentTimeMillis();
	}

	int GAME_END_DISMISS = Constants.GAME_END_DISMISS;

	private void SendData(String jsonData) {
		SendData(Constants.INVALID_CHAIR, jsonData);
	}

	static int log_counter = 0;

	public int m_wDealErrorDelay = 0;

	void OnDealAI(int dt) {

		m_DealTime = (int) (System.currentTimeMillis() / 1000);
		if (m_wChuPaiDelay > 0) {
			m_wChuPaiDelay--;
			return;
		}
		int cntRobot = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 1) {
				cntRobot++;
			}
		}

		int cntActionRight = 0;
		for (int i = 0; i < 4; i++) {
			if (GetActionRight(i) > 0) {
				if (m_pIUserItem[i].isAndroidUser == 1) {
					CleanTempRight(i);
				} else {
					cntActionRight++;
				}
			}
		}

		int cntMoPaiUser = 0;
		for (int j = 0; j < 4; j++) {
			if (m_MajLogic.GetMajSide(j).GetHandMjCount() % 3 == 2) {
				cntMoPaiUser++;
			}
		}
		if (cntMoPaiUser == 0) {
			m_wDealErrorDelay++;
		}
		if (cntActionRight == 0) {

			if (cntMoPaiUser == 0 && m_MajLogic.GetCurrentUser() < 4) {

				if (m_wDealErrorDelay > 1) {
					int byLastUser = m_MajLogic.GetLastUser();
					int byNextUser = Constants.INVALID_CHAIR;
					if (byLastUser == m_MajLogic.GetCurrentUser()) {
						byNextUser = MajHelper.GetNextUser(byLastUser);
					} else {
						byNextUser = m_MajLogic.GetCurrentUser();
					}

					if (m_MajLogic.m_byOutMjCount == 0) {
						byNextUser = m_byZhuang;
					}
					MajSide l_NextMajSide = m_MajLogic.GetMajSide(byNextUser);
					int byHandMjCount = l_NextMajSide.GetHandMjCount();
					if (byHandMjCount % 3 == 1) {
						OnUserTouchMj(byNextUser);
						m_wChuPaiDelay = 1;
						for (int i = 0; i < 4; i++) {
							m_wRobotSeconds[i] = (long) 0;
						}
					} else if (byHandMjCount % 3 == 0) {
						for (int i = Constants.HAND_MJ_MAX - 1; i >= 0; i--) {
							if (l_NextMajSide.Maj[i] != INVALID_CARD) {
								l_NextMajSide.Maj[i] = INVALID_CARD;
								break;
							}
						}
					}
				}
			} else {
				int byCurrentUser = m_MajLogic.GetCurrentUser();
				if (byCurrentUser == 0 || GetActionRight(0) > 0) {
					return;
				}
				m_wRobotSeconds[byCurrentUser]++;
				if (m_pIUserItem[byCurrentUser].isAndroidUser == 1
						&& (m_MajLogic.GetMajSide(byCurrentUser).GetMoPai() != INVALID_CARD)) {
					OnUserOutMj(byCurrentUser, m_MajLogic.GetMajSide(byCurrentUser).GetMoPai());
					for (int i = 0; i < 4; i++) {
						m_wRobotSeconds[i] = 0;
					}
				} else {
					if (m_wRobotSeconds[byCurrentUser] >= 15 && cntRobot != 0) {
						/*
						 * if (m_MajLogic.GetMajSide(byCurrentUser).GetMoPai()
						 * != INVALID_CARD ||
						 * m_MajLogic.GetMajSide(byCurrentUser).GetHandMjCount()
						 * % 3 == 2) {
						 * if(m_MajLogic.GetMajSide(byCurrentUser).GetMoPai() !=
						 * INVALID_CARD) { OnUserOutMj(byCurrentUser,
						 * m_MajLogic.GetMajSide(byCurrentUser).GetMoPai());
						 * }else{ OnUserOutMj(byCurrentUser,
						 * m_MajLogic.GetMajSide(byCurrentUser).GetMoPai()); }
						 * 
						 * for (int i = 0; i < 4; i++) { m_wRobotSeconds[i] = 0;
						 * } }
						 */
					}
				}
			}
		} else {
			if (cntRobot != 0) {
				if (m_wDealErrorDelay > 1) {
					for (int i = 0; i < 4; i++) {
						MajSide l_MajSide = m_MajLogic.GetMajSide(i);
						int byHandMjCount = l_MajSide.GetHandMjCount();
						if (byHandMjCount % 3 == 0) {
							for (int j = Constants.HAND_MJ_MAX - 1; j >= 0; j--) {
								if (l_MajSide.Maj[j] != INVALID_CARD) {
									l_MajSide.Maj[j] = INVALID_CARD;
									break;
								}
							}
						}
					}
				}
				for (int i = 0; i < 4; i++) {
					m_wRobotSeconds[i]++;
					if (m_wRobotSeconds[i] > 600 && GetActionRight(i) > 0
							&& m_MajLogic.GetMajSide(i).GetMoPai() == INVALID_CARD
							&& m_MajLogic.GetMajSide(i).GetHandMjCount() % 3 != 2) {
						SUBCMD_C_Operation guo = new SUBCMD_C_Operation();
						OnUserGiveUp(i, guo);
						CleanTempRight(i);
						m_wRobotSeconds[i] = 0L;
					}
				}
			}
		}
	}

	int INVALID_CARD = Constants.INVALID_CARD;
	int INIT_TOTAL = Constants.INIT_TOTAL;

	public void OnDeal(int dt) {
		if (m_bGameStarted == true) {
			if (GetRobotCount() == GetPlayerCount()) {
				Init(INIT_TOTAL);
			} else {
				OnDealAI(dt);
			}
		}
		if (m_bGameStarted == false) {
		}
	}

	static int randRobotIndex = 999;

	int AddRobot() {

		randRobotIndex++;
		int robot_uid = randRobotIndex % 9999 + 200000;

		ArrayList<Integer> vecEmpty = new ArrayList<>();
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID == 0) {
				vecEmpty.add(i);
			}
		}
		if (vecEmpty.size() > 0) {
			int rand = Constants.rand();
			int wChairID = vecEmpty.get(rand % vecEmpty.size());

			int vecMaleFace[] = { 1, 3, 5, 7, 9 };
			int vecFemaleFace[] = { 2, 4, 6, 8, 10 };
			m_pIUserItem[wChairID].dwUserID = robot_uid;
			m_pIUserItem[wChairID].lUserScore = 0;
			m_pIUserItem[wChairID].wChairID = wChairID;
			m_pIUserItem[wChairID].cbGender = (rand % 2);
			if (m_pIUserItem[wChairID].cbGender == 1) {
				m_pIUserItem[wChairID].dwFaceID = vecMaleFace[rand % 5];
			} else {
				m_pIUserItem[wChairID].dwFaceID = vecFemaleFace[rand % 5];
			}
			m_pIUserItem[wChairID].cbUserStatus = US_NULL;
			m_pIUserItem[wChairID].isAndroidUser = 1;

			m_pIUserItem[wChairID].szNickName = "USER[" + wChairID + "]";

			{
				SUBCMD_S_Sit cmd = new SUBCMD_S_Sit();
				// memset(&cmd, 0, sizeof(cmd));

				cmd.m_lUid = robot_uid;
				cmd.m_wUserChairID = m_pIUserItem[wChairID].wChairID;
				cmd.m_lUserScore = m_pIUserItem[wChairID].lUserScore;
				cmd.m_iAvatar = m_pIUserItem[wChairID].dwFaceID;
				cmd.szNickName = m_pIUserItem[wChairID].szNickName;
				cmd.szIP = m_pIUserItem[wChairID].szIP;

				SendData(cmd.getJsonData());
			}
			{
				m_pIUserItem[wChairID].cbUserStatus = Constants.US_READY;

				SUBCMD_S_Ready cmd = new SUBCMD_S_Ready();
				// memset(&cmd, 0, sizeof(cmd));

				cmd.m_lUid = robot_uid;
				cmd.m_wUserChairID = m_pIUserItem[wChairID].wChairID;

				SendData(cmd.getJsonData());
			}
			m_wRobotSeconds[wChairID] = (long) 0;
			return m_pIUserItem[wChairID].wChairID;
		}
		return 0;
	}

	int US_NULL = Constants.US_NULL;

	void Handle_onJoin(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID < 5) {
			m_pIUserItem[bySeatID].cbOnline = US_NULL;
		}

		SUBCMD_S_Join cmd = new SUBCMD_S_Join();
		// memset(&cmd, 0, sizeof(cmd));

		SendData(_Uid, cmd.getJsonData());
	}

	void Handle_onReady(int _Uid, String[] vecArg) {
		if (m_bGameStarted == true) {
			return;
		}
		int bySeatID = FindSeat(_Uid);
		if (bySeatID < 4) {
			m_pIUserItem[bySeatID].cbUserStatus = Constants.US_READY;
		}
		int cntReady = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].cbUserStatus == Constants.US_READY || m_pIUserItem[i].isAndroidUser == 1) {
				cntReady++;
			}
		}
		SUBCMD_S_Ready cmd = new SUBCMD_S_Ready();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = bySeatID;
		cmd.m_dwTableID = m_dwTableID;
		SendData(cmd.getJsonData());
		if (cntReady == 4) {
			OnEventGameStart();
		} else {

		}
	}

	void Handle_onRobot(int _Uid, String[] vecArg) {
		if (m_bGameStarted == true) {
			return;
		}
		int bySeatID = FindSeat(_Uid);
		if (bySeatID < 4) {
			m_pIUserItem[bySeatID].cbUserStatus = Constants.US_READY;
		}
		int cntPlayer = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				cntPlayer++;
			}
		}
		if (cntPlayer < 4) {
			for (int i = 0; i < 4 - cntPlayer; i++) {
				AddRobot();
			}
		}
	}

	// 摸牌: mopai|bySeatID|byMj|bChi,bPeng,bGang,bTing,bHu
	void Handle_onMoPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID != m_MajLogic.GetCurrentUser()) {
			return;
		}
		OnUserTouchMj(bySeatID);
	}

	// 出牌: chupai|bySeatID|byOutMj|byActionTingPai
	// 出牌:
	// chupai|bySeatID|byMj|bAllowChi,bAllowPeng,bAllowGang,bAllowHu|byTing|byKeHuPai
	void Handle_onChuPai(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);

		if (bySeatID < 4) {
			MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
			int byHandMjCount = l_MajSide.GetHandMjCount();
			if (byHandMjCount % 3 == 0) {
				for (int j = Constants.HAND_MJ_MAX - 1; j >= 0; j--) {
					if (l_MajSide.Maj[j] != INVALID_CARD) {
						l_MajSide.Maj[j] = INVALID_CARD;
						break;
					}
				}
			}
			byHandMjCount = l_MajSide.GetHandMjCount();
			if (byHandMjCount % 3 == 2) {
				m_MajLogic.SetCurrentUser(bySeatID);
				int byOutMj = atoi(vecArg[2]);
				OnUserOutMj(bySeatID, byOutMj);
			}
		}
	}

	// 吃牌: chipai|bySeatID|byChiMj|byChiMode|byOutMj
	void Handle_onChiPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == INVALID_CHAIR) {
			return;
		}
		int byChiMode = atoi(vecArg[2]);
		SUBCMD_C_Chi chi = new SUBCMD_C_Chi();
		chi.nRight = 0;
		chi.nChiType = byChiMode;

		OnUserChi(bySeatID, chi);

		return;
	}

	// 碰牌: pengpai|bySeatID|byPengMj|byOutMj
	void Handle_onPengPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == INVALID_CHAIR) {
			return;
		}

		SUBCMD_C_Operation peng = new SUBCMD_C_Operation();

		OnUserPeng(bySeatID, peng);

		return;

	}

	// 杠牌: gangpai|bySeatID|byGangMj|byGangMode|byBuMj|byAddBaoPai
	void Handle_onGangPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == INVALID_CHAIR) {
			return;
		}

		if (this.m_roundHuCount != 0 && this.IsInRoundHu(bySeatID)) {
			CleanTempRight(bySeatID);
			clearUserHuRound(bySeatID);
			this.m_roundHuGetCount++;
			if (this.m_roundHuCount == this.m_roundHuGetCount) {
				this.Handle_onYiPaoSanXiangHu(bySeatID);
				return;
			}
		}

		int byGangMj = atoi(vecArg[1]);
		int byGangMode = atoi(vecArg[2]);

		SUBCMD_C_Gang gang = new SUBCMD_C_Gang();
		gang.nRight = 0;
		gang.nGangMode = byGangMode;
		gang.byGangMj = byGangMj;

		OnUserGang(bySeatID, gang);

		return;

	}

	// 胡牌: hupai|bySeatID|hu_mode
	void Handle_onHuPai(int _Uid, String[] vecArg) {

		countKehu = Integer.parseInt(vecArg[1]);
		System.err.println("可胡牌：" + countKehu + ".......");
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {
			return;
		}
		if (this.m_roundHuCount != 0) {
			this.m_roundHuGetCount++;
			if (this.m_roundHuCount == this.m_roundHuGetCount)
				this.Handle_onYiPaoSanXiangHu(bySeatID);
		} else {
			SUBCMD_C_Hu hu = new SUBCMD_C_Hu();
			OnUserHu(bySeatID, hu, 1);
		}
		return;

	}

	// 胡牌: hupai|bySeatID|hu_mode
	void Handle_onGuoPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == INVALID_CHAIR) {
			return;
		}

		if (this.m_roundHuCount != 0 && this.IsInRoundHu(bySeatID)) {
			CleanTempRight(bySeatID);
			clearUserHuRound(bySeatID);
			this.m_roundHuSeated[bySeatID] = -1;
			this.m_roundHuGetCount++;
			if (this.m_roundHuCount == this.m_roundHuGetCount) {
				this.Handle_onYiPaoSanXiangHu(bySeatID);
				return;
			}
		}

		SUBCMD_C_Operation guo = new SUBCMD_C_Operation();
		m_isBusy = true;
		OnUserGiveUp(bySeatID, guo);
		m_isBusy = false;
		return;

	}

	int INVALID_CHAIR = Constants.INVALID_CHAIR;

	// 表情
	void Handle_onBiaoQing(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}

		int index = atoi(vecArg[1]);

		SUBCMD_S_BiaoQing cmd = new SUBCMD_S_BiaoQing();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.m_iBiaoQingIndex = index;

		SendData(cmd.getJsonData());
	}

	// 语音
	void Handle_onYuYin(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == INVALID_CHAIR) {

			return;
		}

		int index = atoi(vecArg[1]);

		SUBCMD_S_YuYin cmd = new SUBCMD_S_YuYin();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.m_iYuYinIndex = index;

		SendData(cmd.getJsonData());
	}

	// 语音
	void Handle_onText(int _Uid, String[] vecArg) {

		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}
		String strContent = vecArg[1];
		String iter = dthall.getInstance().m_mapAvatar.get(_Uid);				
		
		String szAvatarURL = "http://lamj.qilehuyu.cn/liuan-80.png";

		if(!StringUtils.isEmpty(iter)){
			m_vecInputWenZi+=iter+";"+_Uid+";"+strContent+",";
		}
		else{
			m_vecInputWenZi+=szAvatarURL+";"+_Uid+";"+strContent+",";
		}
		strContent = string_replace(strContent, "|", ".");
		strContent = string_replace(strContent, "#", ".");
		strContent = string_replace(strContent, ",", ".");
		strContent = string_replace(strContent, "\\", ".");
		strContent = string_replace(strContent, "'", ".");
		strContent = string_replace(strContent, "\"", ".");

		SUBCMD_S_Text cmd = new SUBCMD_S_Text();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.szContent = strContent;
		cmd.InputWenZi=m_vecInputWenZi;
		SendData(cmd.getJsonData());
	}

	private String string_replace(String strContent, String string, String string2) {
		return strContent.replace(string, string2);
	}

	// 送礼
	void Handle_onSongLi(int _Uid, String[] vecArg) {
	}

	// 聊天
	void Handle_onChat(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {

			return;
		}
		String strContent = vecArg[1];

		SUBCMD_S_Chat cmd = new SUBCMD_S_Chat();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.szContent = strContent;
		SendData(cmd.getJsonData());
	}

	// 语音
	void Handle_onVoice(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}
		int seconds = atoi(vecArg[1]);
		String strVoiceURL = vecArg[2];

		System.out.println(strVoiceURL);
		SUBCMD_S_Voice cmd = new SUBCMD_S_Voice();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.seconds = seconds;
		cmd.szVoiceURL = strVoiceURL;

		SendData(cmd.getJsonData());
	}

	void Handle_onVoiceMsg(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}
		float seconds = Float.parseFloat(vecArg[1]);

		SUBCMD_S_VoiceMsg cmd = new SUBCMD_S_VoiceMsg();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.seconds = seconds;

		cmd.data = vecArg[2];
		cmd.m_maxClip = Integer.parseInt(vecArg[3]);
		cmd.m_currClip = Integer.parseInt(vecArg[4]);
		SendData(cmd.getJsonData());
	}

	private int atoi(String string) {
		try {
			return Integer.parseInt(string);
		} catch (Exception e) {
		}
		return 0;
	}

	// 语音
	void Handle_onTryDismissRoom(int _Uid, String vecArg[]) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {
			return;
		}
		if (vecArg.length < 2)
			return;

		String attachInfo = vecArg[1];
		if (attachInfo.equals("fzquit")) {
			// 房主请求直接退出
			OnEventGameEnd(0, Constants.GAME_END_DISMISS);
			DelayRemove();
			QpGameMgr.getInstance().OnDismissRoom(this);
			return;
		}
		int cntUser = 0;
		int cntOnline = 0;
		int cntOffline = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 0 && m_pIUserItem[i].cbOnline == 0) {
				cntUser++;
			}
		}
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 0) {
				if (m_pIUserItem[i].cbOnline == Constants.US_OFFLINE) {
					cntOffline++;
				} else {
					cntOnline++;
				}
			}
		}
		if (cntUser > 1) {
			if (m_dismissTimer == 0) {
				m_dismissTimer = System.currentTimeMillis() / 1000;
			}
			m_byAgreeDismiss[bySeatID] = 1;

			SUBCMD_S_TryDismissRoom cmd = new SUBCMD_S_TryDismissRoom();
			cmd.lUid = _Uid;
			cmd.dwTableID = m_dwTableID;
			cmd.szNickName = m_pIUserItem[bySeatID].szNickName;

			SendData(Constants.INVALID_CHAIR, cmd.getJsonData());

			if (cntOnline == 1) {
				OnEventGameEnd(0, Constants.GAME_END_DISMISS);
				DelayRemove();
				QpGameMgr.getInstance().OnDismissRoom(this);

				m_dismissTimer = 0;
			}
		} else {
			OnEventGameEnd(0, Constants.GAME_END_DISMISS);
			DelayRemove();
			QpGameMgr.getInstance().OnDismissRoom(this);
		}

	}

	// 语音
	void Handle_onAgreeDismissRoom(int _Uid, String vecArg[]) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {
			return;
		}
		if (vecArg.length < 2)
			return;
		m_byAgreeDismiss[bySeatID] = 1;

		SUBCMD_S_AgreeDismissRoom cmd = new SUBCMD_S_AgreeDismissRoom();
		cmd.lUid = _Uid;
		cmd.dwTableID = m_dwTableID;
		cmd.szNickName = m_pIUserItem[bySeatID].szNickName;

		SendData(Constants.INVALID_CHAIR, cmd.getJsonData());

		if (bySeatID == 0 && m_bTableStarted == false) {
			OnEventGameEnd(0, Constants.GAME_END_DISMISS);
			DelayRemove();
			QpGameMgr.getInstance().OnDismissRoom(this);
			return;
		}
		int cntAgree = 0;
		for (int i = 0; i < 4; i++) {
			if (m_byAgreeDismiss[i] > 0) {
				cntAgree++;
			}
		}
		int cntUser = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 0 && m_pIUserItem[i].cbOnline == 0) {
				cntUser++;
			}
		}
		if (cntAgree >= cntUser - 1) {
			OnEventGameEnd(0, Constants.GAME_END_DISMISS);
			DelayRemove();
			QpGameMgr.getInstance().OnDismissRoom(this);

			if (ShouldBeRemoved()) {
				// niuniuTableMgr::instance().DismissTable(this);
			}
		}
	}

	// 语音
	void Handle_onRefuseDismissRoom(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {

			return;
		}

		m_dismissTimer = 0L;
		m_byAgreeDismiss[0] = 0;
		m_byAgreeDismiss[1] = 0;
		m_byAgreeDismiss[2] = 0;
		m_byAgreeDismiss[3] = 0;

		SUBCMD_S_RefuseDismissRoom cmd = new SUBCMD_S_RefuseDismissRoom();
		cmd.lUid = (long) _Uid;
		cmd.dwTableID = m_dwTableID;
		cmd.szNickName = m_pIUserItem[bySeatID].szNickName;

		SendData(cmd.getJsonData());
	}

	void Handle_InBack(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == INVALID_CHAIR) {
			return;
		}

		SUBCMD_S_InBack cmd = new SUBCMD_S_InBack();
		cmd.byActionUser = wChairID;
		SendData(cmd.getJsonData());
	}

	void Handle_InFore(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == INVALID_CHAIR) {
			return;
		}

		SUBCMD_S_InFore cmd = new SUBCMD_S_InFore();
		cmd.byActionUser = wChairID;
		SendData(cmd.getJsonData());
	}

	public int m_DealTime = 0;

	@Override
	public int getDealTime() {
		return m_DealTime;
	}

	public boolean m_bRemove = false;

	public void DelayRemove() {
		m_bRemove = true;
	}

	public void ResetKillFlag() {
		m_bRemove = false;
	}

	public boolean ShouldBeRemoved() {
		return m_bRemove;
	}

	@Override
	public String getRoomInfo() {
		// TODO 自动生成的方法存根
		// m_lStartTime
		// m_pIUserItem
		// m_bTableStarted;
		// m_byRound;
		// m_byMaxRound;
		// m_dwTableID
		String roomInfo = String.format("%s|%s|%s|%s|%s", m_pIUserItem[0].GetUserInfo(), // #
				m_pIUserItem[1].GetUserInfo(), m_pIUserItem[2].GetUserInfo(), m_pIUserItem[3].GetUserInfo(),
				m_pIUserItem[4].GetUserInfo());
		String descInfo = String.format("房间类型：广东麻将 推倒胡  %d/%d局", m_byRound, m_byMaxRound);
		roomInfo = String.format("%s|%d|%d|%s", roomInfo, m_dwTableID, m_lStartTime, descInfo);

		return roomInfo;
	}

	@Override
	public int getPlayerCount() {
		// TODO Auto-generated method stub
		return GetPlayerCount();
	}

	@Override
	public int getCostGem() {
		// TODO Auto-generated method stub
		return m_byCostGem;
	}

	@Override
	public int getStatus() {
		// TODO Auto-generated method stub
		if (m_bTableStarted == false) {
			return 0;
		}
		return 1;
	}

	@Override
	public String getRoomDesc() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getCellScore() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int getMinScore() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String getPayway() {
		return m_payWay;
	}

	@Override
	public String GetRoundInfo() {
		return "" + m_byRound + "/" +  m_byMaxRound;
	}

}

class SUBCMD_C_Operation {
	int byCurrentUser; // 当前用户
	int byLastUser; // 上次出牌用户
	int nRight; // 操作,6-胡,4-杠,3-碰,2-吃, 0-放弃
};

// 用户出牌
class SUBCMD_C_OutMj {
	int byOutMj; // 打出的牌
};

// 吃操作
class SUBCMD_C_Chi {
	int nRight; // 权限
	int nChiType; // 吃牌类型,0-无,1-@@*, 2-@*@, 3-*@@
};

// 碰操作无需参数，所以不单独列

// 杠操作
class SUBCMD_C_Gang {
	int nRight; // 权限
	int nGangMode; // 杠牌类型,0-无, 1-明杠,2-补杠, 4-暗杠
	int byGangMj; // 所杠的牌，自摸可以有多种杠牌的可能
};

// 杠牌选择
class SUBCMD_C_SelectGang {
	int nGangType; // 杠牌类型
	int byGangMj; // 所杠的牌
};

// 胡操作
class SUBCMD_C_Hu {
	int nRight; // 胡牌权限
};

class M_tempAction {
	int m_ActionRight;
	// 用户操作
	SUBCMD_C_Operation m_cOperation = new SUBCMD_C_Operation();
	SUBCMD_C_OutMj m_cChuPai = new SUBCMD_C_OutMj();
	// 吃操作
	SUBCMD_C_Chi m_cChi = new SUBCMD_C_Chi();
	// 碰操作无需参数，所以不单独列
	SUBCMD_C_Operation m_cPeng = new SUBCMD_C_Operation();
	// 杠操作
	SUBCMD_C_Gang m_cGang = new SUBCMD_C_Gang();
	SUBCMD_C_SelectGang m_cSelectGang = new SUBCMD_C_SelectGang();
	// 胡操作
	SUBCMD_C_Hu m_cHu = new SUBCMD_C_Hu();
	// 杠操作
	SUBCMD_C_Operation m_cGuo = new SUBCMD_C_Operation();
	int m_kBuffer[] = new int[100];

	void Clean() {
		Constants.memset(m_kBuffer, 0, 100);
		m_ActionRight = 0;
	}
};

// 用户出牌
class SUBACTION_C_MoPai {
	int byMj; // 打出的牌
};

// 用户出牌
class SUBACTION_C_ChuPai {
	int byMj; // 打出的牌
	int nTing;
};

// 吃操作
class SUBACTION_C_ChiPai {
	int byMj;
	int nChiType; // 吃牌类型,0-无,1-@@*, 2-@*@, 3-*@@
};

// 碰操作无需参数，所以不单独列
// 吃操作
class SUBACTION_C_Peng {
	int byMj;
	int nChiType; // 吃牌类型,0-无,1-@@*, 2-@*@, 3-*@@
};

// 杠操作
class SUBACTION_C_Gang {
	int byMj;
	int nGangMode; // 杠牌类型,0-无, 1-明杠,2-补杠, 4-暗杠
	int byGangMj; // 所杠的牌，自摸可以有多种杠牌的可能
};

// 胡操作
class SUBACTION_C_Hu {
	int byMj;
};

class MJ_Action {
	int m_Action;
	int bySeatID;
	// 摸牌
	SUBACTION_C_MoPai m_cMoPai = new SUBACTION_C_MoPai();
	// 出牌
	SUBACTION_C_ChuPai m_cChuPai = new SUBACTION_C_ChuPai();
	// 吃操作
	SUBACTION_C_ChiPai m_cChi = new SUBACTION_C_ChiPai();
	// 碰操作无需参数，所以不单独列
	SUBACTION_C_Peng m_cPeng = new SUBACTION_C_Peng();
	// 杠操作
	SUBACTION_C_Gang m_cGang = new SUBACTION_C_Gang();
	// 胡操作
	SUBACTION_C_Hu m_cHu = new SUBACTION_C_Hu();

	void Clean() {
		m_Action = 0;
	}
};